我使用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
的悬空连接,并且根本不需要上下文管理器。