Python 避免",;“末日金字塔”;与urllib、urllib2和request的语法类似
很难为响应编写Python2和Python3以及Python 避免",;“末日金字塔”;与urllib、urllib2和request的语法类似,python,request,urllib,try-except,Python,Request,Urllib,Try Except,很难为响应编写Python2和Python3以及request依赖项代码,因为它们urlopen()函数和请求。get()函数返回不同的类型: Python2urllib.request.urlopen()返回一个http.client.HTTPResponse Python3urllib.urlopen(url)返回一个实例 RequestRequest.get(url)返回一个requests.models.Response 为了支持Python2和Python3以及不想安装请求依赖项的
request
依赖项代码,因为它们urlopen()
函数和请求。get()
函数返回不同的类型:
- Python2
返回一个urllib.request.urlopen()
http.client.HTTPResponse
- Python3
返回一个urllib.urlopen(url)
实例
- Request
返回一个Request.get(url)
requests.models.Response
请求
依赖项的用户,我在导入和get_content()函数中尝试了一个看起来像try except
的“末日金字塔”:
try: # Try importing requests first.
import requests
except ImportError:
try: # Try importing Python3 urllib
import urllib.request
except AttributeError: # Now importing Python2 urllib
import urllib
def get_content(url):
try: # Using requests.
return requests.get(url).content # Returns requests.models.Response.
except NameError:
try: # Using Python3 urllib.
with urllib.request.urlopen(index_url) as response:
return response.read() # Returns http.client.HTTPResponse.
except AttributeError: # Using Python3 urllib.
return urllib.urlopen(url).read() # Returns an instance.
是否有其他方法可以达到返回读取内容和避免嵌套的try except
?使用请求对用户有什么好处?更容易忽略请求
并支持标准库函数。这可以通过如下方式导入,对代码的其余部分透明:
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
try:
import requests
get_content = lambda url : requests.get(url).content
except ImportError:
try: # Python 3
from urllib.request import urlopen
except ImportError: # Python2
from urllib2 import urlopen
get_content = lambda url : urlopen(url).read()
从那时起,所有GET请求都可以通过urlopen(url)
发出。可以使用read()
检索返回的数据
现在,如果您确实想继续执行请求
支持,您可以编写导入代码以及get\u content()
的定义,如下所示:
try:
from urllib.request import urlopen
except ImportError:
from urllib2 import urlopen
try:
import requests
get_content = lambda url : requests.get(url).content
except ImportError:
try: # Python 3
from urllib.request import urlopen
except ImportError: # Python2
from urllib2 import urlopen
get_content = lambda url : urlopen(url).read()
正如每个人都提到的,如果您使用的是urllib,那么您不应该为请求操心太多。但是,如果您仍然想避免太多嵌套异常,可以使用下面的方法
import sys
key = str(sys.version_info.major)
try: # Try importing requests first.
import requests
key = "requests"
except ImportError:
try: # Try importing Python3 urllib
import urllib.request
except (AttributeError, ImportError): # Now importing Python2 urllib
import urllib
FUNC = {
"2": {
"urlopen": lambda url: urllib.urlopen(url),
"read": lambda res: res.read()
},
"requests": {
"urlopen": lambda url: requests.get(url),
"read": lambda res: res.content
},
"3": {
"urlopen": lambda url: urllib.request.urlopen(url),
"read": lambda res: res.read()
},
}
urlopen = FUNC[key]["urlopen"]
read = FUNC[key]["read"]
def get_content(url):
res = urlopen(url)
return read(res)
print(get_content("http://tarunlalwani.com"))
您可以尝试将所有三个库作为request
导入,并在get\u content
函数中检查属性以识别导入的库。
作为嵌套的try-except块的替代方法,您可以在单独的try-except块中导入请求
,
这样,如果安装了模块,它将覆盖urllib
/urllib2
try:
import urllib.request as request
except ImportError:
import urllib2 as request
try:
import requests as request
except ImportError:
pass
def get_content(url):
return request.get(url).content if hasattr(request, 'get') else request.urlopen(url).read()
这将生成干净的sipmle代码,并允许您处理更复杂的请求,例如
def get_content(url, headers={}):
if hasattr(request, 'get'):
return request.get(url, headers=headers).content
else:
return request.urlopen(request.Request(url, headers=headers)).read()
如果您不想将请求
作为依赖项,为什么还要麻烦使用请求
?如果您要让它单独使用urllib
,只需使用urllib
。我认为您已经掌握了Python2和Python3的要点。因此建议使用请求
。但是,请参见“#Python 2和3:alternative 4”中的urllib
——对于导入
,只有尝试
。