Python2 到 Python3 是一个较大的版本更新。目前,生产环境依然有大量项目使用的是 Python2。但,这并不意味着项目会一直停留在 Python2,开发者也需要考虑项目对 Python3 的兼容性,以方便迁移,同时也是对新知识的学习。下面是一些学习的知识点整理。
1. Python2 升级 Python3
贸然地升级 Python3 ,无疑将会面临巨大风险。充分地了解 Python2 和 Python3 的区别,学习 Python3 的新特性,预留时间,制定升级计划是必须的。
- 单元测试。
单元测试能跑通,是平稳升级的重要保障。单元测试能够验证升级前后,功能是否一致。如果项目没有单元测试,那么在升级之前应该补上。 - py2 → six → py3。
升级到 Python3,最大的难点在于,改变开发人员的使用习惯。比如,在 Python2 中推荐的 xrange, 在 Python3 中却不能用。开发人员需要一个学习和适应的过程。推荐的策略是,新的功能代码兼容 Python3,逐步重构存量代码。
2. __future__
模块
Python 的新版本会引入新的特性,但是,实际上这些特性在上一个版本中就已经存在。要使用某一新的特性,可以通过导入 __future__
模块来实现。
__future__
包括下面几个新特性:
上面,表中第一列包含了所有可以从 __future__
中导入的特性,optional in 中的版本号为最低可使用的版本,mandatory in 中的版本号为已经实现,无需从 __future__
导入的版本号。最后一列是每个新特性所对应的 PEP 及简单描述。下面是部分 Python3 的新特性示例:
2.1 打印函数
使用 Python3 的 print 函数,禁用 Python2 的 print 语句
|
|
2.2 文本字符串
字符串字面量的类型为文本(Python2 中的 unicode,Python3 中的 str),而不是字节(Python2中的 str,Python3 中的 bytes)。
|
|
2.3 引入模块时,优先绝对路径
使用绝对路径导入模块时,Python 会在 sys.path 里寻找模块。
在Python 2.4 或之前, Python 会先查找当前目录下有没有模块, 若找到了,则引入该模块。
|
|
2.4 使用浮点除法
Python3 中 int 除以 int 得float,而 Python2 使用的是整除。
|
|
3. six 模块
six 是一个专门用来兼容 Python 2 和 Python 3 的库。six 重新定义了在 Python2 和 Python3 中有差异的函数,six 会根据 Python 解释器的版本调用合适的处理函数。
3.1 常量定义兼容
- six.PY2/ six.PY3 ,布尔值。检查编译器版本是否为 Python2 或 Python3
- six.class_types,类类型。在 Python2 中包含旧类和新类。在 Python3 中只是新类
- six.integer_types,整数类型。在 Python2 中是 long 或 int,在 Python3 中是 int
- six.string_types,文本数据的类型。Python2 中是 basestring() , Python3 中是 str
- six.text_type,用于表示(Unicode)文本数据的类型。Python2 中是 unicode() ,Python3 中是 str(Pyhon3 对文本数据进行了整合,默认为 Unicode 文本数据)
- six.binary_type,二进制数据的类型。Python2中是 str,Python3 中是 bytes
- six.MAXSIZE, list 或 dict 等容器的最大尺寸。这相当于 Python 2.6 及更高版本(包括3.x)的 sys.maxsize。在 Python3 中没有直接的等价物, 因为它的整数类型的长度仅受限于内存大小
使用示例:
|
|
3.2 模块位置兼容
Python3 重新组织了很多模块的位置,例如 Python2 的 HTMLParser,在 Python3 中是 html.parser。
可以使用 six 导入,兼容模块导入:
|
|
在大多数情况下,six.moves 别名是 Python3 中模块的名称。
在 这里 ,你可以看到一个 Supported renames 名单。
其他
其他的内容可以在官方的文档找到,基本上就是通过six来调用,而不是自己对Python判断。包括:
3.3 其他
除了上面的兼容性操作,six 还提供了:
- 二进制和文本数据的兼容
- uniittest assert的兼容
- urllib 库改动的兼容
- 高级的自定义move