如果我要创建一个模块,希望在Python 2和Python 3中运行相同的模块,则有很多选项,包括six
,futures
和{{1} }。如果更改的数量很少,那么这些工具中的每一个都有足够的怪癖,我倾向于只为模块实际使用的少数不兼容函数编写一个兼容接口。
一种合理的标准方法是通过简单的版本检查。
2to3
有没有奇怪的情况,import module_bar
if sys.version_info >= (3,):
uniformly_named_foo = module_bar.py3_thing
else:
uniformly_named_foo = module_bar.py2_thing
将无法正确报告?过去,我已经被格式错误的路径,配置,安装,修改以及诸如此类的东西所困扰,这让我觉得这不是我应该信任的东西。
当我们认真研究它时,我真正关心的是是否实现了特定功能。在Web开发中,嗅探用户代理通常被认为是错误的做法。取而代之的是,应该尽力确定是否正在使用特定功能。根据功能的不同,可以通过多种方式实现这一目标。
sys.version_info
在我的机器上,第二条路线的速度是原来的两倍(并不是一次操作确实要多出几百毫微秒),但这似乎没有任何其他主要缺点。有优势吗? 在Python安装中,第二种方法将成功而第一种方法将失败吗?
答案 0 :(得分:1)
是的。 @receiver(post_delete, sender=Person)
def decrement_total_people(sender, instance, **kwargs):
instance.Country.Total_persons -= 1
instance.Country.save()
是确定Python版本的可靠方法。
请参见Python 3 documentation和Python 2 documentation。
注意:sys.version_info
是可靠的,但不是sys.version_info
:
sys.version
一个字符串,其中包含Python解释器的版本号以及有关内部版本号和使用的编译器的其他信息。启动交互式解释器时显示此字符串。 不要从中提取版本信息,而是使用
sys.version
和version_info
模块提供的功能。
如果您担心坏模块会更改platform
的值或其他原因,可以强制重新加载 sys.version_info
:
<module 'sys' (built-in)>
答案 1 :(得分:0)
不,sys.version_info
不可靠,但仅是在某种意义上说,Python中的几乎所有内容都是可重写的,并且因为如果不进行伏都教,模块是单例的。考虑下面的示例,它有一个小的错字。
# bad_dependency.py
import sys
# is_py3 = sys.version_info >= (3,)
is_py3 = sys.version_info = (3,)
当我们导入它时会发生什么?嗯...不好。
# our_module.py
import sys
import bad_dependency
print(sys.version_info)
运行此命令时,由于sys
到处都是相同的模块,并且由于我们已经覆盖了我们关心的信息,因此实际上得到了以下行为:
$ python our_module.py
(3,)
当然,如果导入的bug足够严重,则几乎没有代码是可靠的。有趣的是,不一定是导致问题的代码,而且效果当然不必是恶意的。
关于这样的问题是否在某些合理的标准Python安装(例如micropython,OSX等)中默认是否存在这样的问题,我仍然不确定答案。
答案 2 :(得分:0)
import sys
sys.version_info.major
我认为这是确定是使用Python 2.x还是使用Python 3.x的最佳方法。