【问题标题】:Python help to debug an error when modify a file in a stream modePython在流模式下修改文件时帮助调试错误
【发布时间】:2013-02-08 14:38:04
【问题描述】:

我有以下问题。我正在读取文件 x,y,z 为:

481492.93 6244326.24 26.56
481493.03 6244325.60 25.06
481493.17 6244324.68 22.89
481493.50 6244322.52 17.80
481492.84 6244327.05 27.84
481492.90 6244326.66 26.90
481492.86 6244327.16 27.45
481493.48 6244323.08 17.79
481492.80 6244327.80 28.30
481492.94 6244326.84 26.04
..........................

我希望读取、修改和写入同一个文件(不创建备份文件,因为原始文件超过 10GB)

481492.93 6244326.24 26.56 (375, 2902)
481493.03 6244325.60 25.06 (376, 2902)
481493.17 6244324.68 22.89 (377, 2902)
481493.50 6244322.52 17.80 (379, 2903)
481492.84 6244327.05 27.84 (375, 2902)
481492.90 6244326.66 26.90 (375, 2902)
481492.86 6244327.16 27.45 (374, 2902)
481493.48 6244323.08 17.79 (379, 2903)
481492.80 6244327.80 28.30 (374, 2902)
481492.94 6244326.84 26.04 (375, 2902)
..........................

我写了以下方法

def get_point_grid_id(x,y,x_min,y_max,x_dist,y_dist):
        col = int((x - x_min)/x_dist)
        row = int((y_max - y)/y_dist)
        return (row, col)

with open(file_temp, "r+") as f:
    for line in open(file_temp):
        x,y,z = line.split()
        id = get_point_grid_id(float(x),float(y),origin[0],origin[1],1,1)
        element = [x,y,z,id]
        newelement = " ".join([str(e) for e in element])+ "\n"
        f.write(newelement)

当我运行该函数时,我得到了以下错误

Traceback (most recent call last):
  File "<editor selection>", line 3, in <module>
ValueError: too many values to unpack

我想是原始文件的连接问题

出现错误

>>> x,y,z = line.split()
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ValueError: too many values to unpack

line 很奇怪的地方

'481499.82 6244470.31 29.23 (231, 2909)\n' 

而不是'481499.82 6244470.31 29.23\n'

for line in open(file_temp): 之后使用print line 我从新文件运行后得到了这个打印

481499.98 6244494.02 34.14
481499.98 6244494.02 34.14 (208, 2909)
481499.96 6244471.05 33.39
481499.96 6244471.05 33.39 (231, 2909)
481499.95 6244471.27 33.46
481499.95 6244471.27 33.46 (230, 2909)
481499.98 6244473.84 32.72
481499.98 6244473.84 32.72 (228, 2909)
481499.98 6244474.07 32.70
481499.98 6244474.07 32.70 (228, 2909)
481499.97 6244474.28 32.93
481499.97 6244474.28 32.93 (227, 2909)
481499.88 6244474.40 34.35
481499.88 6244474.40 34.35 (227, 2909)

【问题讨论】:

  • 在执行x,y,z=line.split() 之前尝试执行print line。看起来您可能正在覆盖文件的某些部分。
  • 这行不通(同时读取和写入),因为您正在写出的行比您正在读入的行。那是身体不适合;您将用覆盖的数据超越您的读取操作。
  • with open(file_temp, "r+") as f: 将对您的文件对象的引用分配给 f。 For line in f: 应该跟随而不是再次打开文件。
  • @Gianni:你必须这样做。
  • @EricRoper:我很乐意看到你尝试;输入行比写出的行,因此每个新行都需要比原来的空间更多的空间。您必须先将整个文件读入内存,然后才能重写文件,并且使用 10GB 的输入文件是行不通的。

标签: python debugging error-handling streamwriter


【解决方案1】:

以 r+ 模式打开行意味着您读取了一行,即读取了 38 个字符。 然后你修改这 38 个字符 然后,在当前文件位置(字符 39)覆盖现有数据

我猜这不是你想要的

希望对你有帮助

【讨论】:

  • 亲爱的@Vorsprung 我希望替换(或更新)行添加“id”值
  • Gianni,如果不创建新文件,我没有办法做到这一点——这是你希望避免的。
【解决方案2】:

这行不通。正如Martijn所说,

file 对象有一个缓冲位置。每次读取一个字符时,缓冲区位置都会增加 1。假设您读取的行长度为 10 个字符:

>>> myfile = open('some_file.txt')
>>> myfile.tell() #gets the buffer position
0
>>> myfile.readline()
'012345678\n'

现在缓冲区位置提前len(line) 个字符:

>>> myfile.tell()
10

这意味着当您调用myfile.write() 时,它会从位置 10 开始写入。

如果不覆盖某些内容或将字符附加到末尾(假设缓冲区位置位于文件末尾),您根本无法将字符“插入”到文件中。

那你怎么办?

您可以创建一个临时文件,同时从您的输入文件中读取,并写入您的临时文件。之后(如果您愿意),您可以将原始文件替换为临时文件:

with open(input_file) as infile, open(output_temp_file, "w") as outfile:
    for line in infile:
        x, y, z = line.split()
        new_line = ' '.join([x, y, z] + [function_of_xyz(x, y, z)]) + '\n'
        outfile.write(new_line)

您还应该查看csv module

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多