Python2的最后一个版本是2.7,在2020年彻底停止支持,但在网络上还能时不时地看到Python2的代码。这个时候就要用到
2to3
将其转为python3的语法。
2to3
是Python标准库中自带的一个脚本,可以读取Python2.x的源代码,并应用一系列修复程序将其转换为有效的Python 3.x代码。这个脚本通常会与Python解释器一起安装,位于当前环境Python路径的Tools/scripts
目录中。
转换单个文件
如果只想转换一个名为ex.py的文件,你可以使用以下命令来查看转换后的代码:
2to3 ex.py
这个命令会在标准输出中打印出转换后的代码,并且会显示每一个修改点和对应的修复程序名称。
例如,如果ex.py文件内容如下:
print "Hello, world!"
则运行上面的命令后,你会看到类似以下的输出:
--- ex.py (original)
+++ ex.py (refactored)
@@ -1 +1 @@
-print "hello, world"
+print("hello, world")
其中-
表示删除的原始代码,+
表示添加的新代码。如果对转换后结果满意,则可使用-w
选项来覆盖原始文件:
2to3 -w ex.py
然后ex.py
这个文件就会被修改,而原始文件则会备份到example.py.bak
中。如果在修改的过程中使用-n
选项,则会禁止备份。
转换整个项目
如想转换一个项目,项目中包含多个文件或目录,则可以指定相应的目录列表作为参数:
2to3 proj_dir
这样会递归扫描proj_dir
下所有以.py
结尾的文件,并打印出所有修改点和对应修复程序名称。
和转换单文件相同的是,通过-w
可以直接覆盖原始项目。
修复器
由于Python3与Python2.x在诸多模块处均有不同,所以2to3的修复过程也分门别类,通过指定不同的修复器,可以开启或关闭不同的修复规则。例如,
-
filter
将filter()
变为list(filter())
; -
except
将pyhton2.x中的except X, T
转为except X as T
,等等。 -
input
将input(prompt)
转换为eval(input(prompt))
-
long
将long
重命名为int
-
next
将迭代器的next()
方法转为next()
函数。也会将next()
方法重命名为__next__()
-
urllib
将urllib
和urllib2
重命名为urllib
包。 -
zip
用 list 包装 zip()。如果使用了 from future_builtins import zip 的话会禁用。 -
xrange
将xrange()
重命名为range()
,并用 list 包装原有的 range()。 - …
还有相对复杂的可选修复器,例如
-
idioms
进行多种转换,将Python
代码变成更加常见的写法。类似type(x) is SomeClass
和type(x) == SomeClass
的类型对比会被转换成isinstance(x, SomeClass)
;while 1
转换成while True
,以及类似L = list(some_iterable).sort()
改为L = sorted(some_iterable)
等等。
由于内容很多,就不都贴在这里了。而最关键的改动print xxx
转为print(xxx)
,则通过-p
来调控。
使用2to3 -x xxx
可以禁用xxx
修复器;通过2to3 -f xxx
则表示仅使用xxx
修复器。
通过2to3 -l
可以列举所有修复器。而除了2to3
内置的修复程序之外,还可以编写自己的修复程序,并通过通过lib2to3.fixer_base
中的BaseFix
来自定义修复方法。但lib2to3
已经被标为过时,并且马上就要弃用了,所以就不讲了。