我有一个文件,其中每一行都以数字开头。用户可以通过键入用户想要删除的行号来删除行。
我遇到的问题是设置打开它的模式。当我使用a+
时,原来的内容还在。但是,附加到文件末尾的是我想要保留的行。另一方面,当我使用 w+
时,整个文件都被删除了。我确信有比使用 w+
模式打开它,删除所有内容,然后重新打开它并附加行更好的方法。
def DeleteToDo(self):
print "Which Item Do You Want To Delete?"
DeleteItem = raw_input(">") #select a line number to delete
print "Are You Sure You Want To Delete Number" + DeleteItem + "(y/n)"
VerifyDelete = str.lower(raw_input(">"))
if VerifyDelete == "y":
FILE = open(ToDo.filename,"a+") #open the file (tried w+ as well, entire file is deleted)
FileLines = FILE.readlines() #read and display the lines
for line in FileLines:
FILE.truncate()
if line[0:1] != DeleteItem: #if the number (first character) of the current line doesn't equal the number to be deleted, re-write that line
FILE.write(line)
else:
print "Nothing Deleted"
这是典型文件的样子
1. info here
2. more stuff here
3. even more stuff here
最佳答案
当您打开一个文件进行写入时,您会破坏该文件(删除其当前内容并开始一个新文件)。您可以通过阅读有关 open()
命令的文档来了解这一点。
当您打开一个文件进行追加时,您不会破坏该文件。但是你怎么能只删除一行呢?文件是存储在存储设备上的字节序列;您无法删除一行并让所有其他行自动“滑下”到存储设备上的新位置。
(如果您的数据存储在数据库中,您实际上可以从数据库中删除一个“行”;但文件不是数据库。)
因此,解决此问题的传统方法是:从原始文件中读取,然后将其复制到新的输出文件中。在复制时,您可以执行任何所需的编辑;例如,您可以简单地通过不复制一行来删除该行;或者您可以通过在新文件中写入来插入一行。
然后,一旦您成功写入新文件并成功关闭它,如果没有错误,您继续将新文件重命名回与旧文件相同的名称(这会破坏旧文件)。
在 Python 中,你的代码应该是这样的:
import os
# "num_to_delete" was specified by the user earlier.
# I'm assuming that the number to delete is set off from
# the rest of the line with a space.
s_to_delete = str(num_to_delete) + ' '
def want_input_line(line):
return not line.startswith(s_to_delete)
in_fname = "original_input_filename.txt"
out_fname = "temporary_filename.txt"
with open(in_fname) as in_f, open(out_fname, "w") as out_f:
for line in in_f:
if want_input_line(line):
out_f.write(line)
os.rename(out_fname, in_fname)
请注意,如果您碰巧有一个名为 temporary_filename.txt
的文件,它将被此代码破坏。我们真的不关心文件名是什么,我们可以使用 tempfile
模块让 Python 为我们创建一些唯一的文件名。
任何最新版本的 Python 都允许您在单个 with
语句中使用多个语句,但如果您碰巧使用 Python 2.6 或其他版本,您可以嵌套两个 with
获得相同效果的语句:
with open(in_fname) as in_f:
with open(out_fname, "w") as out_f:
for line in in_f:
... # do the rest of the code
另外,请注意我没有使用.readlines()
方法来获取输入行,因为.readlines()
读取将文件的全部内容一次全部存入内存,如果文件非常大,这将很慢甚至可能无法工作。您可以使用从 open()
返回的“文件对象”简单地编写一个 for
循环;这将一次给你一行,你的程序甚至可以处理非常大的文件。
编辑:请注意,我的回答是假设您只想执行一个编辑步骤。正如@jdi 在对另一个答案的评论中指出的那样,如果您想允许用户可以删除多行或插入行或其他任何内容的“交互式”编辑,那么最简单的方法实际上是使用将所有行读入内存.readlines()
,在结果列表中插入/删除/更新/任何内容,然后在编辑完成后仅将列表写入文件一次。
关于python - 使用 Python 从文本文件中删除一行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11249966/