第 13 章 Python 3支持策略

据我所知,目前Python 3仍然不是任何操作系统的默认Python解释器,尽管它在2008年12月就已经发布了。

如你所知,问题在于Python3和Python 2不兼容。在Python 3发布的时候,Python 2.6和Python 3之间的差异如此之大,以至于人们甚至没有去考虑如何过渡,而只是害怕地耸耸肩。

广告:个人专属 VPN,独立 IP,流量大,速度快,连接稳定,多机房切换,每月最低仅 10 美元

但后来事情发生了变化,Python 2.7从Python 3.1引入了很多新功能,缩小了二者的差距。Python的后续版本变化也趋于理智,而且我可以很高兴地宣布,现在是可以同时支持Python 2.7和Python 3.3的了,几乎没有什么困难。

关于移植应用的官方文档(http://zeromq.org/)是有的,但我不建议不折不扣地参考它。文档中讨论了很多关于2to3工具(将Python 2的代码转换为Python 3),并且包含了一些建议,如为你的项目建立一个特殊的Python 3分支。

在我看来,这是一个糟糕的建议。在几年前这也许是最合适的建议,但考虑到现在Python 2.7和Python 3.3的“兼容”情况,最好还是不要使用这种方法。

 注意

也有3to2工具,但基于上述原因,我并不建议使用。

首先,2to3并不总是对的,它并不是万能的。它只是处理语法的转换,而不维护与Python 2的向后兼容,而且在任何情况下,都需要自己手工处理语义的转换。此外,运行2to3相当慢,因此也很难成为一个长期的解决方案。有些文档甚至建议在setup.py阶段运行它,这多少有点儿碰运气的成分。

有些文档推荐使用不同的项目分支去支持Python 2和Python 3。经验表明这样维护起来相当麻烦,而且用户会困惑该使用哪个版本。更糟糕的是,当用户提交bug但却没有指明用的哪个分支时你会很困惑。

更好的方法就是使用一个代码库并保持对Python 2和Python 3兼容。这也是目前我们在OpenStack上投入精力做的。

最后,确保代码能够对两个Python版本都可用的唯一方式就是单元测试。没有单元测试不可能知道代码在两个上下文环境和不同版本间是否能工作正常。如果应用中还没有任何测试1,那么首先要做的就是大幅增加代码覆盖率,可以回顾一下第6章中的内容。

tox是对多个Python版本进行自动测试的很好的工具,在6.7节中已经介绍过了。

一旦有了单元测试并配置了tox,就很容易使用下面的方法对两个Python版本运行测试:

tox -e py27,py33

根据提示的错误进行修改,重新运行tox,直到所有测试都通过为止。如果做得对的话,错误的数量应该缓慢并稳定下降,从而最终实现代码对Python 2和Python 3的全兼容。

如果有针对Python写的C模块需要移植,那么很抱歉,关于这个没什么好说的,你只能读文档然后移植你的代码。如果可能的话使用cffihttp://cffi.readthedocs.org/en/release-0.8/)选项重写可能会有用。

在后面几节中会讨论一些在不同Python版本间移植可能遇到的问题。这里假设你已经有了一个Python 2的代码库。尽管下面讨论的一些内容可能在理论上也可以用于Python 3到Python 2的移植,但我个人是肯定不会这么干的。