为什么 NamedTemporaryFile().write(没有中间变量)会导致“关闭文件的 I/O 操作”?

AMA*_*nc. 5 python temporary-files destroy

我有以下脚本,它以略有不同的方式两次执行相同的操作。第一个有效,第二个无效:

#!/usr/bin/python
import tempfile

fhandle=tempfile.NamedTemporaryFile(dir=".",delete=False)
fhandle.write("hello")

tempfile.NamedTemporaryFile(dir=".",delete=False).write("hello")
Run Code Online (Sandbox Code Playgroud)

我收到以下错误:

Traceback (most recent call last):
  File "./test.py", line 7, in <module>
     tempfile.NamedTemporaryFile().write("hello")
 ValueError: I/O operation on closed file
Run Code Online (Sandbox Code Playgroud)

在我的示例脚本中,我将它们放在一起以表明第一个有效。这不影响结果,只是指出存在差异。

这是 Python 中的错误吗?我的机器有什么奇怪的吗?预期行为?正确的行为?看起来对象在 write() 之前被销毁。

Ubuntu 12.04.3 LTS 上的 Python 2.7.3

Joh*_*yon 0

我认为 @Eric Urban 和 @alecxe 的评论是正确的,文件已关闭 - 取决于平台 - 基于引用计数或类似的东西。我尝试使用类似的过程查看新创建的临时文件对象:

>>> tempfile.NamedTemporaryFile().__dict__
{'close_called': True, 'name': '/tmp/tmpCRzR_c', 'file': <closed file '<fdopen>', mode 'w+b' at 0x7f9448e541e0>, 'delete': True}

>>> a = tempfile.NamedTemporaryFile()
>>> a.__dict__
{'close_called': False, 'name': '/tmp/tmpnmWpQ5', 'file': <open file '<fdopen>', mode 'w+b' at 0x7f9448e54270>, 'delete': True}
Run Code Online (Sandbox Code Playgroud)

因此,在创建后的一段时间,close将在新创建的临时文件上调用,可能是因为没有对其的引用。根据您的平台和调用方式,关闭文件也可能会删除它。