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