Python 资源管理规范 | Google 官方 with 语句指南

2025-07-30 17:31 更新

文件、套接字 (socket) 和类似的有状态资源

Tip

使用完文件和套接字以后,显式地关闭它们。自然地,这条规则也应该扩展到其他在内部使用套接字的可关闭资源(比如数据库连接)和其他需要用类似方法关停的资源。其他例子还有 mmap 映射、 h5py 的文件对象 和 matplotlib.pyplot 的图像窗口

  1. 如果保持不必要的文件、套接字或其他有状态对象开启,会产生很多缺点: 它们可能消耗有限的系统资源,例如文件描述符。如果代码需要使用大量类似的资源而没有及时返还给系统,就有可能出现原本可以避免的资源枯竭情况。
  2. 保持文件的开启状态会阻碍其他操作,例如移动、删除文件,卸载(unmont)文件系统等等。
  3. 如果程序的多个部分共享文件和套接字,即使逻辑上文件已经关闭了,仍然有可能出现意外的读写操作。如果这些资源真正关闭了,读写操作会抛出异常,让问题早日浮出水面。

此外,即使文件和套接字(以及其他行为类似的资源)会在析构(destruct)时自动关闭,把对象的生命周期和资源状态绑定的行为依然不妥:

  1. 无法保证运行时(runtime)调用 __del__ 方法的真正时机。不同的 Python 实现采用了不同的内存管理技巧(比如延迟垃圾处理机制,delayed garbage collection),可能会随意、无限期地延长对象的生命周期。
  2. 意想不到的文件引用 (例如全局对象和异常的堆栈跟踪, exception tracebacks) 可能让文件的存续时间比想象的更长。

依赖于终结器(finalizer)实现自动清理的方法有显著的副作用。这在几十年的时间里、在多种语言中(参见 这篇 Java 的文章)多次引发严重问题。 推荐使用 “with”语句 管理文件和类似的资源:

with open("hello.txt") as hello_file:
    for line in hello_file:
        print line

对于不支持 with 语句且类似文件的对象, 应该使用 contextlib.closing()

import contextlib


with contextlib.closing(urllib.urlopen("https://www.python.org/")) as front_page:
    for line in front_page:
        print line

少数情况下无法使用基于上下文(context)的资源管理,此时文档应该清楚地解释代码会如何管理资源的生命周期。

以上内容是否对您有帮助:
在线笔记
App下载
App下载

扫描二维码

下载编程狮App

公众号
微信公众号

编程狮公众号