我是 Python 的新手,读了别人的代码:
urllib.urlopen()后面应该跟着 urllib.close()吗? 否则,会泄漏连接,对吗?
urllib.urlopen()
urllib.close()
严格来说,这是真的。但实际上,一旦(如果) urllib超出范围,连接将由自动垃圾收集器关闭。
urllib
在您考虑的时候,必须在 urllib.urlopen的 结果上调用 close方法,在 urllib模块本身上调用 没有方法(正如您提到的 urllib.close——它并不存在)。
urllib.urlopen
close
urllib.close
最佳方法: 不使用 x = urllib.urlopen(u)等,而是使用:
x = urllib.urlopen(u)
import contextlib with contextlib.closing(urllib.urlopen(u)) as x: ...use x at will here...
with语句和 closing上下文管理器将确保即使存在异常也能正确关闭。
with
closing
正如@Peter 所说,范围外打开的 URL 将有资格进行垃圾收集。
不过,请注意 在 CPython URLopener中定义:
URLopener
def __del__(self): self.close()
这意味着 当该实例的引用计数达到零时,它的 __del__方法将被调用,因此它的 close方法也将被调用。引用计数达到零的最“正常”的方法是简单地让实例超出作用域,但是没有什么严格地阻止您尽早使用显式的 del x(然而它并不直接调用 __del__,而只是将引用计数减少一)。
__del__
del x
显式地关闭资源当然是一种很好的风格——特别是当您的应用程序冒着使用过多资源的风险时——但是如果您不做任何有趣的事情,比如维护(循环?) ,Python 威尔会自动为您清理资源对不再需要的实例的引用。
在使用 铁蟒时,基本上 做需要显式关闭连接。超出范围时的自动关闭依赖于垃圾回收。我遇到了这样一种情况: 垃圾收集没有运行太长时间,以至于 Windows 的套接字用完了。我在高频率轮询一个网络服务器(例如,高达 IronPython 和连接将允许,~ 7Hz)。我可以看到“已建立的连接”(即正在使用的套接字)在 PerfMon 上不断增加。解决方案是在每次调用 urlopen之后调用 gc.collect()。
urlopen
gc.collect()
Request 模块使用 HTTP/1.1,并在其 HTTP 请求中包含 Connection:close头。
Connection:close
这是官方文件,你可以检查它 给你。