代码之家  ›  专栏  ›  技术社区  ›  msw

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

  •  2
  • msw  · 技术社区  · 14 年前

    pickle module documentation 下面是一段示例代码:

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

    在第一次读取时,它会分配一个系统文件描述符,读取其内容,然后“泄漏”打开的描述符,因为没有任何句柄可以调用 close() 之后。这让我想知道有没有什么隐藏的魔法来处理这个案子。

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

    上面的示例代码使用的文件对象的持续时间是多少?在该语句执行之后,对象是否确实变得未被引用,因此fd是否受 close(2) 打电话给未来的垃圾回收站?如果是这样,那么示例行是良好实践,还是不应该指望fd被释放,从而冒着每个进程描述符表耗尽内核的风险?

    1 回复  |  直到 14 年前
        1
  •  3
  •   Alex Martelli    14 年前

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

    代码没有 返回 文件对象(正如q的标题正确地说,它作为参数接收)。

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

    依赖于cpython的即时闭包语义(当将来的cpython转移到更好的垃圾收集机制时,这种语义可能会发生变化),虽然这是一种非常传统的方法,但并不是最佳实践。

    相反,最佳实践是使用 with 声明:

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

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

    注意,在Python2.5中,您需要 from __future__ import with_statement 使用 具有 . 在2.6或更高版本中,这样的“从未来导入”并不需要用于此目的(这是无害的,但如果您知道您永远不会在2.5下运行,那么它是多余的,最好删除)。