让urllib在Python 2和3中兼容的好方法

6 投票
2 回答
5221 浏览
提问于 2025-04-18 11:05

我在寻找一些建议,想把这两个代码片段合并在一起,让它们能同时在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())))

撰写回答