我需要在urllib.urlopen()后调用close()吗?

76 投票
5 回答
58647 浏览
提问于 2025-04-15 14:50

我刚开始学习Python,正在阅读别人的代码:

使用urllib.urlopen()之后,应该跟着用urllib.close()吗?不这样做的话,会不会造成连接泄露呢?

5 个回答

6

严格来说,这句话是对的。不过在实际操作中,一旦(如果)urllib 不再被使用,连接就会被自动的垃圾回收器关闭。

14

就像@Peter说的那样,超出作用域的打开的URL会被标记为可以被垃圾回收。

不过,还要注意,在CPython中,URLopener的定义是这样的:

 def __del__(self):
     self.close()

这意味着当这个实例的引用计数变为零时,它的__del__方法会被调用,因此它的close方法也会被调用。引用计数变为零的最“正常”的方式就是让这个实例超出作用域,但你也可以提前用del x来显式删除它(不过这样并不会直接调用__del__,只是把引用计数减一)。

显式关闭资源是个好习惯,特别是当你的应用可能会使用过多资源的时候。但是如果你不做一些奇怪的事情,比如保持(循环)引用那些你不再需要的实例,Python会自动帮你清理这些资源。

109

你需要在使用 urllib.urlopen 得到的结果上调用 close 方法,而不是urllib 模块上调用(你提到的 urllib.close 是不存在的)。

最好的做法是:不要这样写 x = urllib.urlopen(u) 等等,而是使用:

import contextlib

with contextlib.closing(urllib.urlopen(u)) as x:
   ...use x at will here...

使用 with 语句和 closing 上下文管理器,可以确保即使出现错误也能正确关闭。

撰写回答