简体   繁体   English

Python-打开文本文件进行编辑,然后使用fileinput.input()对其进行修改

[英]Python - Opening a text file for edition before modifiying it in place with fileinput.input()

I have a python script used to edit a text file . 我有一个用于编辑text filepython script Firstly, the first line of the text file is removed. 首先,删除text filefirst line After that, a line is added to the end of the text file . 之后,在text file的末尾添加一行。
I noticed a weird phenomenon, but I cannot explain the reason of this behaviour: 我注意到了一个奇怪的现象,但是我无法解释这种现象的原因:

This script works as expected (removes the first line and adds a line at the end of the file): 该脚本按预期工作(删除第一行,并在文件末尾添加一行):

import fileinput

# remove first line of text file
i = 0
for line in fileinput.input('test.txt', inplace=True):
    i += 1    
    if i != 1:
        print line.strip()

# add a line at the end of the file
f = open('test.txt', 'a+') # <= line that is moved
f.write('test5')
f.close()

But in the following script, as the text file is opened before removing, the removal occurs but the content isn't added (with the write() method): 但是在以下脚本中,由于在删除之前打开了text file ,因此会发生删除,但不会添加内容(使用write()方法):

import fileinput

# file opened before removing
f = open('test.txt', 'a+') # <= line that is moved

# remove first line of text file
i = 0
for line in fileinput.input('test.txt', inplace=True):
    i += 1    
    if i != 1:
        print line.strip()

# add a line at the end of the file
f.write('test5')
f.close()

Note that in the second example, open() is placed a the beginning, whereas in the first it is called after removing the last line of the text file . 请注意,在第二个示例中, open()放在开头,而在第一个示例中,在删除text file的最后一行之后调用它。

What's the explanation of the behaviour? 行为的解释是什么?

When using fileinput with the inplace parameter, the modified content is saved in a backup file. 当使用fileinputinplace参数,修改的内容保存在备份文件。 The backup file is renamed to the original file when the output file is closed. 关闭输出文件后,备份文件将重命名为原始文件。 In your example, you do not close the fileinput file explicitly, relying on the self-triggered closing, which is not documented and might be unreliable. 在您的示例中,您没有依靠自动触发的关闭来显式关闭fileinput文件,该关闭没有记录,并且可能不可靠。

The behaviour you describe in the first example is best explained if we assume that opening the same file again triggers fileinput.close() . 如果我们假设再次打开同一文件会触发fileinput.close() ,则可以最好地解释您在第一个示例中描述的行为。 In your second example, the renaming only happens after f.close() is executed, thus overwriting the other changes (adding "test5"). 在第二个示例中,仅在执行f.close()之后才进行重命名,从而覆盖其他更改(添加“ test5”)。

So apparently you should explicitly call fileinput.close() in order to have full control over when your changes are written to disk. 因此,显然,您应该显式调用fileinput.close() ,以便完全控制将更改写入磁盘的时间。 (It is generally recommended to release external resources explicitly as soon as they are not needed anymore.) (通常建议在不再需要外部资源时立即将其释放。)

EDIT: 编辑:

After more profound testing, this is what I think is happening in your second example: 经过更深入的测试之后,我认为这是您的第二个示例中发生的情况:

  • You open a stream with mode a+ to the text file and bind it to the variable f . 您以模式a+打开流到文本文件,并将其绑定到变量f
  • You use fileinput to alter the same file. 您可以使用fileinput更改相同的文件。 Under the hood, a new file is created, which is afterwards renamed to what the file was called originally. 在后台,将创建一个新文件,然后将其重命名为该文件最初的名称。 Note: this doesn't actually change the original file – rather, the original file is made inaccessible, as its former name now points to a new file. 注意:这实际上并不会更改原始文件-而是使原始文件不可访问,因为其以前的名称现在指向一个新文件。
  • However, the stream f still points to the original file (which has no file name anymore). 但是,流f仍指向原始文件(该文件不再具有文件名)。 You can still write to this file and close it properly, but you cannot see it anymore (since it has no filename anymore). 您仍然可以写入该文件并正确关闭它,但是您再也看不到它了(因为它不再具有文件名了)。

Please note that I'm not an expert in this kind of low-level operations; 请注意,我不是这种底层操作的专家; the details might be wrong and the terminology certainly is. 细节可能是错误的,术语肯定是错误的。 Also, the behaviour might be different across OS and Python implementations. 而且,行为在OS和Python实现之间可能有所不同。 However, it might still help you understand why things go different from what you expected. 但是,它仍然可以帮助您了解为什么事情与您期望的有所不同。

In conclusion I'd say that you shouldn't be doing what you do in your second example. 总之,我要说的是您不应该在第二个示例中做您所要做的。 Why don't you just read the file into memory, alter it, and then write it back to disk? 您为什么不只是将文件读入内存,对其进行更改,然后再将其写回到磁盘? Actual in-place (on-disk) altering of files is no fun in Python, as it's too high-level a language. 在Python中进行文件的实际就地(磁盘上)更改并不是一件好事,因为它是一种高级语言。

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

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