【问题标题】:Can relying on python3 to automatically close the files result in an unexpected behaviour?依赖 python3 自动关闭文件会导致意外行为吗?
【发布时间】:2021-08-11 23:57:31
【问题描述】:

下面的实现会不会出错?

def ReadFromFile(file_name):
    return [line for line in open(file_name)]

def AppendToFile(new_line, file_name):
    open(file_name, 'a').write(new_line)

在读取/写入文件后,我没有显式调用close() 方法。我的理解是,从语义上讲,程序必须表现得好像文件总是在每个函数结束时关闭一样。

这些函数的以下使用是否会产生意想不到的结果,例如

original_lines = ReadFromFile("file.txt")
for line in original_lines:
    AppendToFile(line, "file.txt")
modified_lines = ReadFromFile("file.txt")

我希望例如len(modified_lines) == len(original_lines) * 2。不能这样吗?

【问题讨论】:

  • 你为什么不使用with open(...)?这将确保文件已关闭。
  • @balderman 需要额外的标识块,代码变得稍微不太可读 IMO
  • 不要为了简洁而牺牲正确性……!?额外的块明确说明了文件何时以及如何打开和关闭……
  • @deceze 所以我的问题是:我是否正在牺牲正确性?有什么可能出错的情况吗?

标签: python python-3.x file file-io


【解决方案1】:

当我们使用任何写入函数写入文件时。 Python 将要写入文件的所有内容保存在缓冲区中,并将其推送到存储设备上的实际文件中,无论是在 Python 文件的末尾还是遇到close() 函数时。

另外,如果我们用相同的文件对象打开另一个文件,那么第一个文件将被 python 关闭,例如:

   file_object1 = open(file1,'r')
   file_object1 = open(file2, 'r')

在这种情况下,file1 也会自动关闭

因此,如果文件在两者之间终止,则数据不会存储在文件中。所以我建议两个选择:

  • 使用with,因为一旦您离开该块或遇到任何异常,它就会关闭文件,

       with open(filename , file_mode) as file_object:
               do the file manipulations........
    
  • 如果你想强制 python 将缓冲区的内容写入存储而不关闭文件,你可以使用flush() 函数。

    file_object.flush()
    

供参考: https://lerner.co.il/2015/01/18/dont-use-python-close-files-answer-depends/

【讨论】:

  • “在 python 文件的末尾” - 不,当文件对象超出范围时
  • @mercury0114 你能以某种方式支持这个断言吗?
  • @mercury0114 如果在两者之间我们更改文件句柄的值,你是对的,例如,打开另一个具有相同 file_object 的文件,然后它也会关闭文件,但是当 python 文件结束时,对象将自动超出范围,所以这不是错误的
猜你喜欢
  • 2016-05-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多