我应该在urllib.urlopen()之后调用close()吗?

Nik*_*ita 70 python urllib

我是Python新手并阅读其他人的代码:

应该urllib.urlopen()跟着urllib.close()?否则,一个人会泄漏连接,对吗?

Ale*_*lli 102

close必须在结果上调用该方法urllib.urlopen,而不是urllib您考虑的模块本身上调用(正如您所提到的urllib.close- 哪些不存在).

最好的方法:x = urllib.urlopen(u)使用:代替等,使用:

import contextlib

with contextlib.closing(urllib.urlopen(u)) as x:
   ...use x at will here...
Run Code Online (Sandbox Code Playgroud)

with声明,以及closing上下文管理器,将确保即使在例外的存在正确关闭.

  • 在Python 3中,添加了对with语句的直接支持.用urllib.urlopen(u)作为x:... (14认同)
  • 做什么像`data = urllib2.urlopen('url').read()` (11认同)

Mar*_*off 12

就像@Peter所说的那样,超出范围的打开的URL将有资格进行垃圾回收.

但是,还要注意urllib.py定义:

 def __del__(self):
        self.close()
Run Code Online (Sandbox Code Playgroud)

这意味着当该实例的引用计数达到零时,__del__将调用其close方法,因此也将调用其方法.引用计数达到零的最"正常"方式是简单地让实例超出范围,但没有什么能严格阻止你从del x早期显式(但它不直接调用__del__但只是将引用计数减少一个) ).

明确关闭资源肯定是好的方式 - 特别是当你的应用程序冒着使用过多资源的风险时 - 如果你不做任何有趣的事情,如维护(循环?)引用,Python 自动为你清理到你不再需要的实例.

  • 但是,有可能超出垃圾收集器 - 我遇到的情况是我创建文件句柄的速度比关闭它们要快[但是在显式的`gc.collect()`调用或者`close()` ,清理东西]. (2认同)

Pet*_*ter 5

严格来说,这是真的。但实际上,一旦 (if)urllib超出范围,连接将被自动垃圾收集器关闭。

  • Python 的某些实现确实如此,但是 Python 语言并不能保证一旦对象超出范围就会关闭。参见 杰通 (11认同)
  • @Piotr,但是如果我有一个循环打开 url 并且 GC 没有足够快地收割它们,程序可能会崩溃。这是一种非常草率的做事方式,不属于生产代码。 (3认同)
  • 无操作 GC(即,永远不会运行的 GC)对于 Python 来说是完全有效的。您无法保证 GC 会运行。而 `gc.disable` 可以在大多数 Python 实现中禁用 GC。 (2认同)