使用'a+'时file.readline()的意外输出

4 投票
2 回答
63 浏览
提问于 2025-04-14 17:53

一开始,我有一个名为 new_file 的文本文件,里面存储着 1\n2\n3\n4\n5\n 这些内容。

我运行了以下的 Python 程序:

f = open('new_file', 'a+')

f.write('\n'.join(str(i) for i in range(1, 6)))
f.seek(0)

print(f.readlines())

f.seek(0)
f.write("\nFinal Line")

print(f.readlines())

f.close()

我原本期待这个程序会先把 1\n2\n3\n4\n5 添加到 new_file 文件中,然后打印出 ['1\n', '2\n', '3\n', '4\n', '5\n', '1\n', '2\n', '3\n', '4\n', '5'],最后再把 \nFinal Line 添加到 new_file 文件中,并打印出 ['1\n', '2\n', '3\n', '4\n', '5\n', '1\n', '2\n', '3\n', '4\n', '5\n', 'Final line']

文件的内容变化是我预期的那样,但程序打印出的内容却是:

['1\n', '2\n', '3\n', '4\n', '5\n', '1\n', '2\n', '3\n', '4\n', '5']
['1\n', '2\n', '3\n', '4\n', '5\n', '1\n', '2\n', '3\n', '4\n', '5']

这为什么会发生呢?

2 个回答

0

你应该使用w+模式,而不是a+模式,并且你的第二个seek语句放在了第二个写入语句的错误位置。

为了达到你想要的结果,你的代码应该是:

f = open('new_file', 'w+')

f.write('\n'.join(str(i) for i in range(1, 6)))
f.seek(0)

print(f.readlines())


f.write("\nFinal Line")
f.seek(0)

print(f.readlines())

f.close()

输出结果是:

['1\n', '2\n', '3\n', '4\n', '5']
['1\n', '2\n', '3\n', '4\n', '5\n', 'Final Line']

如果你必须使用a+模式,那么你的代码应该是:

import os

f = open('new_file2', 'a+')

f.write('\n'.join(str(i) for i in range(1, 6)))
f.seek(0)

print(f.readlines())


f.write("\nFinal Line")
f.seek(0)

print(f.readlines())

f.close()
os.remove(f.name)

输出结果也将是:

['1\n', '2\n', '3\n', '4\n', '5']
['1\n', '2\n', '3\n', '4\n', '5\n', 'Final Line']
0

根据fopen的说明,如果文件是以a+模式打开的,那么“输出总是会被追加到文件的末尾”。所以在最后一次调用readlines()之前,你需要先使用seek(0)来确保能看到整个文件的内容。

import os

try:
    os.remove("new_file")
except FileNotFoundError:
    pass

with open('new_file', 'a+') as f:
    f.write('\n'.join(str(i) for i in range(1, 6)))
    f.seek(0)
    print(f.readlines())
    # file pointer is now at EOF for reading
    f.write("\nFinal Line")
    # seek to BOF
    f.seek(0)
    print(f.readlines())

输出:

['1\n', '2\n', '3\n', '4\n', '5']
['1\n', '2\n', '3\n', '4\n', '5\n', 'Final Line']

撰写回答