sys.version_info 对于 Python 版本检查是否可靠?

Han*_*ave 8 python python-2.7 python-3.x

如果我做了一个模块,我想作为在Python 3运行在Python 2相同,有一吨的选项包括sixfutures,和2to3。如果更改的数量很少,那么这些工具中的每一个都有足够的怪癖,我倾向于只为我的模块实际使用的少数不兼容功能编写兼容接口。

实现这一点的合理标准方法是使用简单的版本检查。

import module_bar

if sys.version_info >= (3,):
    uniformly_named_foo = module_bar.py3_thing
else:
    uniformly_named_foo = module_bar.py2_thing
Run Code Online (Sandbox Code Playgroud)

是否有任何奇怪的情况sys.version_info不会正确报告?过去,我已经被格式错误的路径、配置、安装、修改以及诸如此类的东西所困扰,以至于我觉得这不是我应该信任的事情。

当我们深入研究它时,我真正关心的是是否实现了特定功能。在 Web 开发中,嗅探用户代理通常被认为是一种不好的做法。相反,应该尽最大努力确定某个特定功能是否正在使用中。根据功能的不同,有很多方法可以实现这一点。

if hasattr(module_bar, 'py3_thing'):
    uniformly_named_foo = module_bar.py3_thing
else:
    uniformly_named_foo = module_bar.py2_thing
Run Code Online (Sandbox Code Playgroud)

在我的机器上,第二条路线慢两倍(对于一次性操作来说,额外的几百纳秒并不重要),但它似乎没有任何其他主要缺点。还是有优势?是否存在第二种方法会成功而第一种方法会失败的 Python 安装?

iBu*_*Bug 8

是的。sys.version_info是确定 Python 版本的可靠方法。

请参阅Python 3 文档Python 2 文档

注意:sys.version_info是可靠的,但不是sys.version

系统版本

一个字符串,其中包含 Python 解释器的版本号以及有关所用版本号和编译器的附加信息。该字符串在交互式解释器启动时显示。不要从中提取版本信息,而是使用模块version_info提供的功能platform

如果你担心坏模块改变的值sys.version_info或别的东西,你可以强制重装<module 'sys' (built-in)>

import sys
sys.version_info = "boo"
print(sys.version_info)  # boo

sys.modules.pop("sys")
import sys  # reloaded
print(sys.version_info)
# Output: sys.version_info(major=3, minor=6, ...
Run Code Online (Sandbox Code Playgroud)