修改线路

Modifying lines

我想要加载一个文件并将几个预定义的行修改为特定值。 以下是我尝试过的:

with open("test.txt",'w') as f:
                for i,line in f:
                    if (i == 2):
                        f.writelines(serial1)
                    if (i == 3):
                        f.writelines(serial2)
                    if (i == 4):
                        f.writelines(serial3)
                    else:
                        f.writelines(line)

但是,当运行代码出现以下错误时:

for i,line in f:
io.UnsupportedOperation: not readable

我做错了什么?

您以只写方式(w 模式)打开文件并尝试读取它 - 这是由 for 语句完成的。

即:在读取文件时使用 for 语句遍历文件。

如果您打算写入它,文件本身的 for 帮不了您 - 只需使用带 "range" 的普通计数器并写入即可。

with open("test.txt",'w') as f:
    for i in range(desired_lines):
        if (i == 2):
            f.write(serial1 + "\n")
        if (i == 3):
            f.write(serial2 + "\n")
        if (i == 4):
            f.write(serial3 + "\n")
        else:
            f.write(line + "\n")

此外,当您有要写入的字符串列表时,应使用 writelines, 每个单独的行 - 你不显示你的变量的内容,但鉴于你想要确切的行号,它看起来像 writelines 不是你想要的。

(附带说明 - 注意缩进 - 你应该为你在 Python 中输入的每个块确定一个固定的数量 - 它会像你一样使用任意标识,但在 Python代码)

更新 看起来您只需要更改现有文本文件的某些行。到目前为止,最好的方法是重新创建另一个文件,替换你想要的行,然后重命名所有内容。 (写入文本文件几乎不可行,因为所有文本行都必须与以前存在的行大小相同 - 并且在低级磁盘访问中仍然一无所获)。

import os

...

lines_to_change{
    2: serial1,
    3: serial2,
    4: serial3,
}

with open("test.txt",'rt') as input_file, open("newfile.txt", "wt") as output_file:
    for i, line in enumerate(input_file):
        if i in lines_to_change:
            output_file.write(lines_to_change[i] + '\n')
        else:
            output_file.write(line)

os.rename("test.txt", "test_old.txt")
os.rename("newfile.txt", "test.txt")
os.unlink("test_old.txt")

如前所述,您的问题是您试图在同一个文件中读写。最简单的方法是打开一个新文件,并在获得所需输出后替换第一个文件。

要获取文件行数,可以使用enumerate:

with open("test.txt",'r') as f:
                for i,line in enumerate(f):
                    if (i == 2):
                        f.writelines(serial1)
                    if (i == 3):
                        f.writelines(serial2)
                    if (i == 4):
                        f.writelines(serial3)
                    else:
                        f.writelines(line)

你所做的就是就地编辑。为此,Python 标准库 fileinput 可以提供帮助:

import fileinput

for line in fileinput.input('test.txt', inplace=True):
    if fileinput.lineno() == 2:
        print serial1
    elif fileinput.lineno() == 3:
        print serial2
    elif fileinput.lineno() == 4:
        print serial3
    else:
        print line

更新

至于"What I'm doing wrong?"有一对:

  • 您打开文件是为了写入,您如何从中读取?您可能会尝试将模式从 "w" 更改为 "r+",即读取和写入。这就带来了另一个困境:读取第 2 行后,文件指针位于第 3 行的开头,你写的任何内容都会覆盖第 3 行,更不用说新旧行之间的长度差异了。最好写入一个新的临时文件,然后在完成后将其复制回原始文件,或者您可以使用 fileinput 如上所示。
  • for i, line in f 不起作用,我想你的意思是 for i, line in enumerate(f, 1)
  • 压痕特别深是怎么回事?
  • if语句应该是if ... elif ... else。目前您的 else 子句仅附加到 if i == 4 语句,而不是其他两个。