2024-06-16 13:33:46 发布
网友
在我的印象中,当文件对象的引用计数达到0时,它们会立即关闭,因此行:
foo = open('foo').read()
会得到文件的内容并立即关闭文件。然而,在阅读了对Is close() necessary when using iterator on a Python file object的答案之后,我得到的印象是,这不会发生,并且对文件对象调用.close()始终是必需的。
.close()
上面这条线是不是做了我认为它在做的事情,即使它做了,这是不是Python的事情?
对于python的cpython实现:是,当它的引用计数变为零时,它保证关闭。
对于作为抽象语言的python(例如,包括Jython、IronPython等):不,不保证它是关闭的。特别是,Python的实现可以选择不使用引用计数,而是使用其他形式的GC。
参考资料:
答案在你提供的链接中。
垃圾收集器在销毁文件对象时将关闭文件,但是:
你真的无法控制事情的发生。
而CPython使用引用计数来确定地释放资源 (所以您可以预测对象何时被销毁)其他版本不必。 例如,Jython或IronPython都使用JVM和.NET垃圾收集器 仅当需要恢复内存时才释放(和完成)对象 在程序结束之前可能不会对某个对象执行此操作。 甚至对于CPython,GC算法在将来也可能作为引用计数而改变 效率不高。
如果在关闭文件对文件对象销毁时引发异常, 你真的什么都做不了,因为你不知道。
如果你想确定,我会这样写代码:
from __future__ import with_statement with open('foo') as f: foo = f.read()
这样,您的文件将按预期关闭,即使有例外。
稍后:下面是一些带有import dis的代码,以显示编译器如何区别对待这些代码。
import dis
>>> def foo(filename): ... with open(filename) as f: ... return f.read() ... >>> def bar(filename): ... return open(filename).read() ... >>> from dis import dis >>> >>> dis(foo) 2 0 LOAD_GLOBAL 0 (open) 3 LOAD_FAST 0 (filename) 6 CALL_FUNCTION 1 9 DUP_TOP 10 LOAD_ATTR 1 (__exit__) 13 ROT_TWO 14 LOAD_ATTR 2 (__enter__) 17 CALL_FUNCTION 0 20 STORE_FAST 1 (_[1]) 23 SETUP_FINALLY 23 (to 49) 26 LOAD_FAST 1 (_[1]) 29 DELETE_FAST 1 (_[1]) 32 STORE_FAST 2 (f) 3 35 LOAD_FAST 2 (f) 38 LOAD_ATTR 3 (read) 41 CALL_FUNCTION 0 44 RETURN_VALUE 45 POP_BLOCK 46 LOAD_CONST 0 (None) >> 49 WITH_CLEANUP 50 END_FINALLY 51 LOAD_CONST 0 (None) 54 RETURN_VALUE >>> dis(bar) 2 0 LOAD_GLOBAL 0 (open) 3 LOAD_FAST 0 (filename) 6 CALL_FUNCTION 1 9 LOAD_ATTR 1 (read) 12 CALL_FUNCTION 0 15 RETURN_VALUE
对于python的cpython实现:是,当它的引用计数变为零时,它保证关闭。
对于作为抽象语言的python(例如,包括Jython、IronPython等):不,不保证它是关闭的。特别是,Python的实现可以选择不使用引用计数,而是使用其他形式的GC。
参考资料:
答案在你提供的链接中。
垃圾收集器在销毁文件对象时将关闭文件,但是:
你真的无法控制事情的发生。
而CPython使用引用计数来确定地释放资源 (所以您可以预测对象何时被销毁)其他版本不必。 例如,Jython或IronPython都使用JVM和.NET垃圾收集器 仅当需要恢复内存时才释放(和完成)对象 在程序结束之前可能不会对某个对象执行此操作。 甚至对于CPython,GC算法在将来也可能作为引用计数而改变 效率不高。
如果在关闭文件对文件对象销毁时引发异常, 你真的什么都做不了,因为你不知道。
如果你想确定,我会这样写代码:
这样,您的文件将按预期关闭,即使有例外。
稍后:下面是一些带有
import dis
的代码,以显示编译器如何区别对待这些代码。相关问题 更多 >
编程相关推荐