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

时间:2009-10-05 21:59:05

标签: python urllib

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

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

5 个答案:

答案 0 :(得分:97)

必须在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...

with语句和closing上下文管理器将确保即使存在异常也能正常关闭。

答案 1 :(得分:12)

与@Peter一样,超出范围的已打开网址将有资格进行垃圾回收。

但是,请注意urllib.py定义:

 def __del__(self):
        self.close()

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

明确关闭资源肯定是好的方式 - 特别是当你的应用程序冒着使用太多所述资源的风险时 - 但是如果你不这样做,Python 自动为你清理做一些有趣的事情,比如维护(循环?)对你不再需要的实例的引用。

答案 2 :(得分:4)

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

答案 3 :(得分:0)

使用 IronPython 时,您基本上要做需要明确关闭连接。超出范围时自动关闭取决于垃圾回收。我遇到了这样一种情况,即垃圾收集没有运行很长时间,以至于Windows用尽了套接字。我正在以较高的频率轮询网络服务器(即与IronPython一样高,并且连接允许〜7Hz)。我可以看到“已建立的连接”(即正在使用的套接字)在PerfMon上不断上升。解决方案是在每次调用gc.collect()之后再调用urlopen

答案 4 :(得分:0)

<块引用>

urllib.request 模块使用 HTTP/1.1 并在其 HTTP 请求中包含 Connection:close 标头。

来自官方文档,您可以查看here