您的代码已经删除了第一个字符。我将您的代码完全保存为dupy.py
and dupy.txt
,然后运行python dupy.py dupy.txt
,结果是:
from sys import argv
run, filename = argv
f = open(filename, 'a+')
f.seek(0)
lines = f.readlines()
for line in lines:
f.write(line[1:])
f.close()
rom sys import argv
un, filename = argv
= open(filename, 'a+')
.seek(0)
ines = f.readlines()
or line in lines:
f.write(line[1:])
.close()
它不是复制整行;它正在复制行,而它们的第一个字符被剥离。
但是从问题的最初陈述来看,听起来您想覆盖这些行,而不是附加新副本。为此,请不要使用append
模式。读取文件,然后写入:
from sys import argv
run, filename = argv
f = open(filename)
lines = f.readlines()
f.close()
f = open(filename, 'w')
for line in lines:
f.write(line[1:])
f.close()
或者,或者,编写一个新文件,然后在完成后将其移动到原始文件之上:
import os
from sys import argv
run, filename = argv
fin = open(filename)
fout = open(filename + '.tmp', 'w')
lines = f.readlines()
for line in lines:
fout.write(line[1:])
fout.close()
fin.close()
os.rename(filename + '.tmp', filename)
(请注意,此版本在 Windows 上无法按原样运行,但它比实际的跨平台版本更简单;如果您需要 Windows,我可以解释如何执行此操作。)
with
您可以通过使用语句、直接循环文件而不是调用来使代码更简单、更健壮和更高效readlines
,并使用tempfile
:
import tempfile
from sys import argv
run, filename = argv
with open(filename) as fin, tempfile.NamedTemporaryFile(delete=False) as fout:
for line in fin:
fout.write(line[1:])
os.rename(fout.name, filename)
在大多数平台上,这保证了“原子写入”——当你的脚本完成时,或者即使有人在它运行的过程中拔掉了插件,文件最终要么被新版本替换,要么原封不动;它不可能在中途被覆盖成不可恢复的垃圾。
同样,此版本无法在 Windows 上运行。如果没有大量工作,就无法在 Windows 上实现这种“写临时重命名”算法。但是您只需做一些额外的工作就可以接近:
with open(filename) as fin, tempfile.NamedTemporaryFile(delete=False) as fout:
for line in fin:
fout.write(line[1:])
outname = fout.name
os.remove(filename)
os.rename(outname, filename)
这确实可以防止您半覆盖文件,但它会留下一个漏洞,您可能已经删除了原始文件,并将新文件留在了您必须搜索的临时位置。您可以通过将文件放在更容易找到的地方来使它更好一点(请参阅NamedTemporaryFile
文档以了解如何)。或者将原始文件重命名为临时名称,然后写入原始文件名,然后删除原始文件。或其他各种可能性。但是要真正获得与其他平台相同的行为是非常困难的。