不要再写出不能在 Python 4 中运行的程序了

533 查看

随着终止支持 Python 2 的脚步越来越近(至2020年),为了兼容 Python 2 和 Python 3,许多 Python 包的开发者会使用下面的代码:

在某些方面,Python2 和 Python3 是存在差异的。

six 通过提供一层包装,简化了差异,使得代码在 Python 2 和 Python 3 中可以有相同的行为。举一个例子,通常遍历字典的 key 一般这样做:

在 Python2 中:

在 Python 3 中,使用 six:

这种方法在 Python 2 和 Python 3 中可以无缝运行。但是,一些比较复杂的情况如本文开篇展示的例子,就需要借助 if 来实现。同样地,six 通过提供 PY2PY3 两个布尔常量来简化操作。

这种方法目前为止还不错。

这就引出了本文的主题,我们确实不知道 Python 4 将会是什么样子,但我们可以肯定的是,从 Python 3 向 Python 4 过渡会很流畅,不会像 Python3 一样无法向后兼容,如果是这样的话,我们就可以无缝地使用为 Python 2 和 Python3 开发的工具包了。

但是情况并非完全如此。通过在 Github 上搜寻,匹配到了大约 300,000个结果,使用了下面这种语法:

发现问题了吗?在 six 中,PY3是这样定义的:

所以,一旦 Python 4 开始应用,PY2PY3 的值将会为 False。对于 Python 2 ,上述的 if 判断中都将执行 else

下面再看一个有问题的代码:

在这种情况下,Python 4 中将不会执行任何代码!

为了避免出现这个问题,关键在于我们应该避免在上述 if 声明判断时把 Python 3 当做特例,而是将 Python 2 当做特例,Python 3 作为默认条件:

这是一个小改动,但会在以后省去很多让人头疼的问题。所以,如果你在开发 Python 包,检查下你的代码以确保兼容 Python 4。

更新:当然,不使用 six,也能实现相同的逻辑。如果通过 sys.version_info 进行版本比较,确保不要这样用:

检查 Python 2 版本的代码时,要么交换 if 声明中判断的内容,要么确保使用 >=