这行python在完成后会关闭文件吗?

sta*_*ser 2 python

我有一行python通过回车符分割文件:

lines = open(sFile, 'r').read().split("0d".decode('hex'))
Run Code Online (Sandbox Code Playgroud)

这个文件是关闭的吗?如果没有,我可以以某种方式获取文件句柄吗?

mgi*_*son 8

简短的回答是"可能".打开的文件对象应该收集垃圾,这将关闭文件.但是,在某些情况下可能不是这样,并且打开的文件句柄可以继续存在.

最佳做法是始终关闭文件句柄.背景管理者的美丽在这里很难高估:

with open(sFile) as input_file:
    lines = input_file.read().split('0d'.decode('hex'))
Run Code Online (Sandbox Code Playgroud)

我们在评论中询问是否可以证明文件对象是隐式关闭的.我不知道这个问题的答案,但是,我们可以证明在当前语句甚至完成执行之前,垃圾收集器可以获取文件对象.因为它是相当普遍的知识,当收获了我们可以做什么一些假设文件对象被关闭可以在OP的情况下发生的.

from __future__ import print_function
import weakref

def callback(*args):
    print('cleanup')

fobj = weakref.ref(open('test.dat'), callback)()
print(fobj)
Run Code Online (Sandbox Code Playgroud)

如果你会发现,cleanup被前打印None(并且weakref.ref回报None),这意味着我们的文件对象已经被垃圾收集器收获参考调用之前1.

1注意,这是CPython的行为.在pypy-2.6.1上运行它,文件对象此时仍处于活动状态,cleanup永远不会被打印!这支持了您应该关闭自己的文件句柄的声明,因为GC运行时肯定存在实现依赖性(因此,文件句柄将被关闭并重新获取).


ale*_*cxe 6

垃圾收集器可能会隐式关闭该文件.还有更多:

建议在处理文件或类文件对象时使用with上下文管理器:

with在处理文件对象时,最好使用关键字.这样做的好处是文件在套件完成后正确关闭,即使在途中引发了异常.它也比编写等效的try-finally块短得多

with open(sFile) as input_file:
    lines = input_file.read().split("0d".decode('hex'))
Run Code Online (Sandbox Code Playgroud)