就地修改文本文件(读写文本文件)
modify text file in place (read and write text file)
当我尝试修改我的一个文本文件时,我在 python 中遇到了 file.readlines()
和 file.writelines()
的奇怪行为。你能帮我理解这种意想不到的行为吗?真是让我很困惑。
这是一个简单的例子,可以用来重现奇怪的行为:
我知道我可以通过阅读文本内容、更改文本以及使用下面的 方法 1 等 2 个上下文管理器写入文本来修改文本,它工作得很好并且非常健壮(我总是得到我所期望的):
方法一
with open("sample.txt","r")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
with open("sample.txt","w")as file:
file.writelines(content)
sample.txt:
a = -1
v = -3
vv
abc
c=1
输出文件:
a = 1
v = 3
v
abc
c=1
不过,我尽量省力打字,遵循“DRY”原则。我改用了以下代码(我相信我在堆栈溢出的某个地方看到了它)。这真的让我很惊讶,也让我很痛苦地找到了这个问题。它有时工作得很好,有时它不依赖于文本文件。
方法二
with open("sample.txt","r+")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
file.seek(0)
file.writelines(content)
使用相同的输入文本文件,它输出以下文本文件:
a = 1
v = 3
v
abc
c=1
=1
我非常好奇方法2输出的文本文件中的最后一行=1
,除了那一行,其他似乎都是正确的。你能解释一下那条线的产生吗?
更新
我们仍然可以使用单个上下文管理器就地修改文本文件,但是为了避免现有文件的残留,我们需要查找文件的开头并将其完全截断。
with open("sample.txt","r+")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
file.seek(0)
file.truncate(0)
file.writelines(content)
当您以 r+
模式打开文件并返回开头时,您将覆盖从该位置开始的字节,但该位置 之后 的字节将不会被替换。
您看到的 =1
是旧内容的残余,在您用比以前包含的字符串更短的字符串替换文件的开头之后。
当我尝试修改我的一个文本文件时,我在 python 中遇到了 file.readlines()
和 file.writelines()
的奇怪行为。你能帮我理解这种意想不到的行为吗?真是让我很困惑。
这是一个简单的例子,可以用来重现奇怪的行为: 我知道我可以通过阅读文本内容、更改文本以及使用下面的 方法 1 等 2 个上下文管理器写入文本来修改文本,它工作得很好并且非常健壮(我总是得到我所期望的):
方法一
with open("sample.txt","r")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
with open("sample.txt","w")as file:
file.writelines(content)
sample.txt:
a = -1
v = -3
vv
abc
c=1
输出文件:
a = 1
v = 3
v
abc
c=1
不过,我尽量省力打字,遵循“DRY”原则。我改用了以下代码(我相信我在堆栈溢出的某个地方看到了它)。这真的让我很惊讶,也让我很痛苦地找到了这个问题。它有时工作得很好,有时它不依赖于文本文件。
方法二
with open("sample.txt","r+")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
file.seek(0)
file.writelines(content)
使用相同的输入文本文件,它输出以下文本文件:
a = 1
v = 3
v
abc
c=1
=1
我非常好奇方法2输出的文本文件中的最后一行=1
,除了那一行,其他似乎都是正确的。你能解释一下那条线的产生吗?
更新
我们仍然可以使用单个上下文管理器就地修改文本文件,但是为了避免现有文件的残留,我们需要查找文件的开头并将其完全截断。
with open("sample.txt","r+")as file:
content = file.readlines()
content[0] = "a = 1\n"
content[2] = "v = 3\n"
content[3] = "v\n"
file.seek(0)
file.truncate(0)
file.writelines(content)
当您以 r+
模式打开文件并返回开头时,您将覆盖从该位置开始的字节,但该位置 之后 的字节将不会被替换。
您看到的 =1
是旧内容的残余,在您用比以前包含的字符串更短的字符串替换文件的开头之后。