让urllib在Python 2和3中兼容的好方法
我在寻找一些建议,想把这两个代码片段合并在一起,让它们能同时在Python 2和Python 3中运行。我的目标是让代码看起来“整洁”,最好能保持在一行内,并尽量减少使用if/else/try/except这样的结构。
对于Python 3.x
import xml.etree.ElementTree as ET, urllib.request, gzip, io
url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urllib.request.urlopen(url).read())))
对于Python 2.x
import xml.etree.ElementTree as ET, urllib, gzip, io
url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urllib.urlopen(url).read())))
2 个回答
11
这正是six
这个库的用处。它是为了让你的代码可以同时在Python 2和Python 3上运行而设计的。(别被“库”这个词吓到,它其实只是一个简单的.py文件,方便你集成和使用。)
你不需要使用内置的urllib
模块,而是可以使用six提供的版本,这个版本会自动在Python 2和3中重定向到相应的内置模块。
你的代码看起来会是这样的:
import xml.etree.ElementTree as ET, gzip, io
from six.moves.urllib.request import urlopen
url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urlopen(url).read())))
详细信息请查看:https://six.readthedocs.io/#module-six.moves.urllib.request
13
如果你不想增加额外的依赖,可以简单地使用一个 try
except
代码块来在同一个别名下导入任意一个模块……:
try:
import urllib.request as urlrequest
except ImportError:
import urllib as urlrequest
url = "https://github.com/OpenExoplanetCatalogue/oec_gzip/raw/master/systems.xml.gz"
oec = ET.parse(gzip.GzipFile(fileobj=io.BytesIO(urlrequest.urlopen(url).read())))