【发布时间】:2021-11-08 05:47:46
【问题描述】:
我是 Python 新手,正在阅读别人的代码:
urllib.urlopen() 后面应该跟urllib.close() 吗?否则,会泄漏连接,对吗?
【问题讨论】:
我是 Python 新手,正在阅读别人的代码:
urllib.urlopen() 后面应该跟urllib.close() 吗?否则,会泄漏连接,对吗?
【问题讨论】:
close 方法必须在 urllib.urlopen 的 result 上调用,而不是在 urllib 模块本身上调用,正如您正在考虑的那样(当您提及urllib.close——不存在)。
最好的方法:代替x = urllib.urlopen(u)等,使用:
import contextlib
with contextlib.closing(urllib.urlopen(u)) as x:
...use x at will here...
with 语句和 closing 上下文管理器将确保即使存在异常也能正确关闭。
【讨论】:
data = urllib2.urlopen('url').read()这样的事情怎么样
contextlib.closing?
urllib.urlopen 根本不存在。
就像@Peter 所说,超出范围打开的 URL 将有资格进行垃圾收集。
不过,还要注意urllib.py 定义:
def __del__(self):
self.close()
这意味着当该实例的引用计数为零时,它的__del__ 方法将被调用,因此它的close 方法也将被调用。引用计数达到零的最“正常”方式是简单地让实例超出范围,但没有什么严格阻止您尽早使用显式 del x(但是它不直接调用 __del__ 而只是将引用计数减一)。
明确关闭你的资源肯定是一种很好的方式——尤其是当你的应用程序冒着使用过多上述资源的风险时——但是如果你不这样做,Python 会自动为你清理做一些有趣的事情,比如维护(循环?)对不再需要的实例的引用。
【讨论】:
gc.collect() 调用或 @ 987654329@,收拾东西]。
严格来说,这是真的。但实际上,一旦(如果)urllib 超出范围,自动垃圾收集器将关闭连接。
【讨论】:
gc.disable 可以在大多数 Python 实现中禁用 GC。
您基本上确实需要在使用 IronPython 时显式关闭您的连接。超出范围的自动关闭依赖于垃圾收集。我遇到了一种情况,即垃圾收集没有运行很长时间,以至于 Windows 用完了套接字。我以高频率轮询网络服务器(即与 IronPython 一样高,并且连接允许,~7Hz)。我可以看到“已建立的连接”(即正在使用的套接字)在 PerfMon 上不断上升。解决方案是在每次调用urlopen 后调用gc.collect()。
【讨论】:
urllib.request 模块使用 HTTP/1.1 并在其 HTTP 请求中包含
Connection:close标头。
来自官方文档,您可以查看here。
【讨论】: