简体   繁体   English

在Python中打开输入和输出文件

[英]Open a file for input and output in Python

I have the following code which is intended to remove specific lines of a file. 我有以下代码,旨在删除文件的特​​定行。 When I run it, it prints the two filenames that live in the directory, then deletes all information in them. 当我运行它时,它会打印出目录中的两个文件名,然后删除其中的所有信息。 What am I doing wrong? 我究竟做错了什么? I'm using Python 3.2 under Windows. 我在Windows下使用Python 3.2。

import os

files = [file for file in os.listdir() if file.split(".")[-1] == "txt"]

for file in files:
    print(file)
    input = open(file,"r")
    output = open(file,"w")

    for line in input:
        print(line)
        # if line is good, write it to output

    input.close()
    output.close()

open(file, 'w') wipes the file. open(file, 'w')擦除文件。 To prevent that, open it in r+ mode (read+write/don't wipe), then read it all at once, filter the lines, and write them back out again. 为防止这种情况,请在r+模式下打开它(读取+写入/不擦除),然后立即读取所有内容,过滤行并再次将其写回。 Something like 就像是

with open(file, "r+") as f:
    lines = f.readlines()              # read entire file into memory
    f.seek(0)                          # go back to the beginning of the file
    f.writelines(filter(good, lines))  # dump the filtered lines back
    f.truncate()                       # wipe the remains of the old file

I've assumed that good is a function telling whether a line should be kept. 我认为good是一个函数,告诉我是否应该保留一条线。

If your file fits in memory, the easiest solution is to open the file for reading, read its contents to memory, close the file, open it for writing and write the filtered output back: 如果您的文件适合内存,最简单的解决方案是打开文件进行读取,将其内容读取到内存,关闭文件,打开文件进行写入并将过滤后的输出写回:

with open(file_name) as f:
    lines = list(f)
# filter lines
with open(file_name, "w") as f:      # This removes the file contents
    f.writelines(lines)

Since you are not intermangling read and write operations, the advanced file modes like "r+" are unnecessary here, and only compicate things. 由于您不是在进行读写操作,因此这里不需要像"r+"这样的高级文件模式,只能编译。

If the file does not fit into memory, the usual approach is to write the output to a new, temporary file, and move it back to the original file name after processing is finished. 如果文件不适合内存,通常的方法是将输出写入新的临时文件,并在处理完成后将其移回原始文件名。

One way is to use the fileinput stdlib module. 一种方法是使用fileinput stdlib模块。 Then you don't have to worry about open/closing and file modes etc... 那么你不必担心打开/关闭和文件模式等...

import fileinput
from contextlib import closing
import os

fnames = [fname for fname in os.listdir() if fname.split(".")[-1] == "txt"] # use splitext
with closing(fileinput.input(fnames, inplace=True)) as fin:
    for line in fin:
        # some condition
        if 'z' not in line: # your condition here
            print line, # suppress new line but adjust for py3 - print(line, eol='') ?

When using inplace=True - the fileinput redirects stdout to be to the file currently opened. 当使用inplace inplace=True - fileinput将stdout重定向到当前打开的文件。 A backup of the file with a default '.bak' extension is created which may come in useful if needed. 创建具有默认“.bak”扩展名的文件备份,如果需要,可能会有用。

jon@minerva:~$ cat testtext.txt
one
two
three
four
five
six
seven
eight
nine
ten

After running the above with a condition of not line.startswith('t') : 运行上面的条件not line.startswith('t')

jon@minerva:~$ cat testtext.txt
one
four
five
six
seven
eight
nine

You're deleting everything when you open the file to write to it. 当您打开要写入的文件时,您将删除所有内容。 You can't have an open read and write to a file at the same time. 您不能同时打开和写入文件。 Use open(file,"r+") instead, and then save all the lines to another variable before writing anything. 改为使用open(file,"r+") ,然后在写入任何内容之前将所有行保存到另一个变量。

You should not open the same file for reading and writing at the same time. 您不应该同时打开同一个文件进行读写。

"w" means create a empty for writing. “w”表示为写作创建一个空。 If the file already exists, its data will be deleted. 如果该文件已存在,则其数据将被删除。

So you can use a different file name for writing. 因此,您可以使用不同的文件名进行编写。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM