参数列表中文件对象的python持续时间

时间:2010-03-23 01:33:30

标签: python internals

pickle module documentation中有一段示例代码:

reader = pickle.load(open('save.p', 'rb'))

在第一次读取时看起来它会分配一个系统文件描述符,读取它的内容,然后“泄漏”打开的描述符,因为没有任何句柄可以访问close()。这让我想知道是否有任何隐藏的魔法可以解决这个问题。

潜入源代码,我在Modules / _fileio.c中发现文件描述符被fileio_dealloc()析构函数关闭,这导致了真正的问题。

上面示例代码使用的文件对象的持续时间是多少?在该语句执行之后,该对象确实变为未引用,因此fd将在未来的垃圾收集扫描中受到真正的close(2)调用吗?如果是这样,那么示例行是不是很好的做法,还是一个人不应该指望fd被释放,从而冒着内核每进程描述符表耗尽的风险?

1 个答案:

答案 0 :(得分:3)

  

文件的持续时间是多少   示例代码返回的对象   以上?

该代码不返回文件对象(正如Q的标题所说,它接收它作为参数)。

在当前的CPython中,文件将在函数返回时关闭(因为该函数不会将对文件对象的任何引用存储到更持久的位置)。在其他实现中,文件将“最终”关闭,但没有指定精确的时间。

取决于CPython的即时关闭语义(当未来的CPython转向更好的垃圾收集机制时可能会改变),虽然这是一种非常传统的方法,但并不是最佳实践。

相反,最佳做法是使用with语句:

with open(...) as f:
  reader = pickle.load(f)

使用 this ,在所有实现中都保证文件的立即关闭(只要with语句的主体结束)。

请注意,在Python 2.5中,您需要from __future__ import with_statement才能使用with。在2.6或更高版本中,为此目的不需要这样的“从未来导入”(它是无害的,但是如果你知道你将永远不会在2.5下运行它是多余的并且更好地删除了。)