Python:通过contextlib关闭打开的URL



我使用urllib.request定期检查我是否连接到了互联网,所以我担心打开太多实例。我使用以下代码关闭它们:

from urllib.request import urlopen 
from contextlib import closing
def internet_on():
try:
with closing(urlopen('http://google.com', timeout=1)) as x:
return True
except BaseException as err: 
return False`

这是防止打开实例的有效方法吗?

简单回答:urlopen总是返回一个对象,该对象是上下文管理器,因此应该能够执行以下操作:

def internet_on():
try:
with urlopen('http://google.com', timeout=1):
return True
except urllib.error.URLError: 
return False

也就是说,使用contextlib.closing()在这里没有添加任何内容。

也就是说,这里有一些额外的想法:

(1( 您不应该使用BaseException——它非常广泛,应该很少直接使用。例如,即使代码中断,您也会得到False,并且由于引入了一些中断更改,将永远不会工作。找出哪些更具体的异常类型可能会因为TCP连接错误而发生,或者当由于连接问题而失败时可能会合理抛出的任何异常类型,然后只捕获这些异常类型。

(2( 你是否看到了一个实际的太多开放连接的问题,或者你只是担心它?

HTTP(广义地说(是一种无状态协议,AFAIKurlopen在发出请求后不会特意保持连接的打开,一旦你进入with上下文,你就不太可能得到一个仍然打开的连接——到那时,要么请求已经完成,连接已经关闭,要么它已经失败,urllib会在你到达那里之前抛出(可能会关闭它自己的TCP连接(。因此,除非您正在做一些特别的事情,否则我确信您不会看到与urlopen的悬空连接,并且根本不需要上下文管理器。

最新更新