should I call close() after urllib.urlopen()?
我对python不太熟悉,而且还阅读别人的代码:
urllib.urlopen()后面应该跟urllib.close()吗?否则,会泄漏连接,对吗?
必须对urllib.urlopen的结果调用close方法,而不是您所考虑的urllib模块本身调用(正如您提到的urllib.close方法不存在)。
最佳方法:使用:
1 2 3 4
| import contextlib
with contextlib.closing(urllib.urlopen(u)) as x:
...use x at will here... |
with声明和closing上下文管理器将确保在出现异常的情况下适当关闭。
- 做点像data = urllib2.urlopen('url').read()的事怎么样?
- 在Python3中,添加了对WITH语句的直接支持。以urllib.urlopen(u)为x:…
- 为什么python3文档在这个(ahem)上下文中仍然提到contextlib.closing?
正如@peter所说,超出范围的开放URL将成为垃圾收集的条件。
但是,也要注意,urllib.py定义了:
1 2
| def __del__(self):
self.close() |
号
这意味着当该实例的引用计数为零时,将调用它的__del__方法,因此也将调用它的close方法。引用计数达到零的最"正常"的方法是简单地让实例超出范围,但是没有什么严格地阻止您过早地从一个显式的del x中退出(但是它不是直接调用__del__,而是将引用计数减少一个)。
显式关闭资源当然是一种很好的方式——特别是当应用程序存在使用过多所述资源的风险时——但是如果您不做像维护(循环?)这样有趣的事情,Python将自动为您清理资源。引用您不再需要的实例。
- 但是,有可能会溢出垃圾收集器——我曾经遇到过这样的情况:创建文件句柄的速度比关闭文件句柄的速度要快[但是在这种情况下,一个显式的gc.collect()调用,或者一个close()清除了所有的内容]。
严格来说,这是真的。但在实践中,一旦(如果)urllib超出范围,连接将由自动垃圾收集器关闭。
- 这在一些Python实现中是正确的,但是Python语言不能保证一旦对象超出范围,就将立即关闭。参照Jython
- @这个答案的作者Gnibbler并没有说,只要它发生,它就会发生。
- @piotr,但是如果我有一个循环打开URL,并且GC没有足够快地获取它们,那么程序可能会崩溃。这是一种相当草率的做事方式,不属于生产代码。
- no-op gc(即从不运行的gc)对于python是完全有效的。你不能保证GC会运行。在大多数Python实现中,gc.disable可以禁用GC。
- 在GC执行任何清理之前,我设法用尽了可用的连接。所以是的,如果你不想突然发现连接中断,你应该打电话给close。
在使用Ironpython时,基本上需要显式地关闭连接。超出范围时自动关闭依赖于垃圾收集。我遇到了这样一种情况:垃圾收集没有运行太久,以至于窗口的套接字用完。我正在以高频率(即高达Ironpython和连接允许的频率,~7hz)轮询一个Web服务器。我可以看到"已建立的连接"(即使用中的套接字)在PerfMon上不断增加。解决方法是在每次呼叫urlopen之后呼叫gc.collect()。