2to 3-自动python 2到3代码转换¶
2to3是一个python程序,它读取python 2.x源代码并应用一系列 固定器 将其转换为有效的python 3.x代码。标准库包含一组丰富的修复程序,可以处理几乎所有代码。2to3支持库 lib2to3
不过,它是一个灵活的通用库,因此可以为2to3编写自己的修复程序。
使用2to3¶
2to3通常与python解释器一起作为脚本安装。它也位于 Tools/scripts
python根目录。
2to3的基本参数是要转换的文件或目录的列表。对于python源,目录是递归遍历的。
下面是一个示例python 2.x源文件, example.py
::
def greet(name):
print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)
它可以通过命令行上的2to 3转换为python 3.x代码:
$ 2to3 example.py
将打印与原始源文件的差异。2to3还可以将所需的修改直接写回源文件。(备份原始文件,除非 -n
也给出。)使用 -w
flag:
$ 2to3 -w example.py
改造后, example.py
如下所示:
def greet(name):
print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)
在整个翻译过程中保留注释和精确的缩进。
默认情况下,2to3运行一组 predefined fixers . 这个 -l
标记列出所有可用的修复程序。可以使用 -f
. 同样地 -x
显式禁用修复程序。以下示例仅运行 imports
和 has_key
固定器:
$ 2to3 -f imports -f has_key example.py
此命令运行除 apply
固定器:
$ 2to3 -x apply example.py
有些修理工是 明确的 ,这意味着默认情况下它们不会运行,必须在要运行的命令行中列出。这里,除了默认的修复程序外, idioms
固定器运行:
$ 2to3 -f all -f idioms example.py
注意如何通过 all
启用所有默认修复程序。
有时2to3会在源代码中找到需要更改的位置,但2to3无法自动修复。在这种情况下,2to3将在文件的diff下打印警告。为了使3.x代码符合要求,您应该处理警告。
2to3还可以重构doctests。要启用此模式,请使用 -d
flag。注意 only 将重构doctest。这也不要求模块是有效的python。例如,REST文档中类似于doctest的示例也可以使用此选项进行重构。
这个 -v
选项允许输出有关翻译过程的更多信息。
由于某些print语句可以解析为函数调用或语句,因此2to3不能总是读取包含print函数的文件。当2to3检测到 from __future__ import print_function
编译器指令,它修改其内部语法以解释 print()
作为一种功能。也可以使用手动启用此更改 -p
标志。使用 -p
对已经转换了print语句的代码运行修复程序。阿尔索 -e
可用于制作 exec()
功能。
这个 -o
或 --output-dir
选项允许为要写入的已处理输出文件指定备用目录。这个 -n
当将此用作备份文件时,如果不覆盖输入文件,则需要使用标志。
3.2.3 新版功能: 这个 -o
选项已添加。
这个 -W
或 --write-unchanged-files
标志告诉2to3即使文件不需要更改,也要始终写入输出文件。这对 -o
这样,通过从一个目录到另一个目录的转换,可以复制整个Python源码树。此选项意味着 -w
标记,否则就没有意义。
3.2.3 新版功能: 这个 -W
增加了标志。
这个 --add-suffix
选项指定要附加到所有输出文件名的字符串。这个 -n
将此指定为写入不同文件名时不需要备份时需要标志。例子:
$ 2to3 -n -W --add-suffix=3 example.py
将导致名为 example.py3
要写。
3.2.3 新版功能: 这个 --add-suffix
选项已添加。
要将整个项目从一个目录树转换为另一个目录树,请执行以下操作:
$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode
固定器¶
转换代码的每一步都封装在一个固定器中。命令 2to3 -l
列出它们。AS documented above ,每个都可以单独打开和关闭。这里对它们进行了更详细的描述。
- apply¶
删除的用法
apply()
. 例如apply(function, *args, **kwargs)
转换为function(*args, **kwargs)
.
- asserts¶
替换已弃用的
unittest
方法名和正确的方法名。从
到
failUnlessEqual(a, b)
assertEquals(a, b)
failIfEqual(a, b)
assertNotEquals(a, b)
failUnless(a)
assert_(a)
failIf(a)
failUnlessRaises(exc, cal)
failUnlessAlmostEqual(a, b)
assertAlmostEquals(a, b)
failIfAlmostEqual(a, b)
assertNotAlmostEquals(a, b)
- buffer¶
皈依者
buffer
到memoryview
. 此修复程序是可选的,因为memoryview
API类似,但与buffer
.
- dict¶
修复字典迭代方法。
dict.iteritems()
转换为dict.items()
,dict.iterkeys()
到dict.keys()
和dict.itervalues()
到dict.values()
.同样地,dict.viewitems()
,dict.viewkeys()
和dict.viewvalues()
分别转换为dict.items()
,dict.keys()
和dict.values()
. 它还包含了dict.items()
,dict.keys()
和dict.values()
在调用中list
.
- except¶
皈依者
except X, T
到except X as T
.
- funcattrs¶
修复已重命名的函数属性。例如,
my_function.func_closure
转换为my_function.__closure__
.
- future¶
移除
from __future__ import new_feature
声明。
- getcwdu¶
更名
os.getcwdu()
到os.getcwd()
.
- has_key¶
变化
dict.has_key(key)
到key in dict
.
- idioms¶
这个可选的修复程序执行几个转换,使Python代码更加惯用。类型比较如下
type(x) is SomeClass
和type(x) == SomeClass
转换为isinstance(x, SomeClass)
.while 1
变成while True
. 这个修理工也试图利用sorted()
在适当的地方。例如,此块:L = list(some_iterable) L.sort()
更改为:
L = sorted(some_iterable)
- import¶
检测同级导入并将其转换为相对导入。
- imports¶
处理标准库中的模块重命名。
- input¶
皈依者
input(prompt)
到eval(input(prompt))
.
- intern¶
皈依者
intern()
到sys.intern()
.
- isinstance¶
修复的第二个参数中的重复类型
isinstance()
. 例如,isinstance(x, (int, int))
转换为isinstance(x, int)
和isinstance(x, (int, float, int))
转换为isinstance(x, (int, float))
.
- itertools_imports¶
删除的导入
itertools.ifilter()
,itertools.izip()
和itertools.imap()
. 输入itertools.ifilterfalse()
也更改为itertools.filterfalse()
.
- itertools¶
更改的用法
itertools.ifilter()
,itertools.izip()
和itertools.imap()
它们的内置等价物。itertools.ifilterfalse()
已更改为itertools.filterfalse()
.
- map¶
包裹
map()
在一个list
调用。它也改变了map(None, x)
到list(x)
. 使用from future_builtins import map
禁用此修复程序。
- metaclass¶
转换旧的元类语法 (
__metaclass__ =meta``在类体中)到新的 (``class X(metaclass=Meta)
)
- methodattrs¶
修复旧方法属性名。例如,
meth.im_func
转换为meth.__func__
.
- ne¶
转换旧的不相等语法,
<>
,至!=
.
- next¶
转换迭代器的使用
next()
方法到next()
功能。它也重命名next()
方法到__next__()
.
- nonzero¶
更名
__nonzero__()
到__bool__()
.
- numliterals¶
将八进制文字转换为新语法。
- operator¶
将调用转换为
operator
模块到其他但等效的函数调用。当需要时,适当的import
添加语句,例如import collections.abc
. 进行以下映射:从
到
operator.isCallable(obj)
callable(obj)
operator.sequenceIncludes(obj)
operator.contains(obj)
operator.isSequenceType(obj)
isinstance(obj, collections.abc.Sequence)
operator.isMappingType(obj)
isinstance(obj, collections.abc.Mapping)
operator.isNumberType(obj)
isinstance(obj, numbers.Number)
operator.repeat(obj, n)
operator.mul(obj, n)
operator.irepeat(obj, n)
operator.imul(obj, n)
- paren¶
在列表理解中需要它们的地方添加额外的括号。例如,
[x for x in 1, 2]
变成[x for x in (1, 2)]
.
- raise¶
皈依者
raise E, V
到raise E(V)
和raise E, V, T
到raise E(V).with_traceback(T)
. 如果E
是一个元组,转换将不正确,因为已在3.0中删除了用元组替换异常。
- reduce¶
处理的移动
reduce()
到functools.reduce()
.
- reload¶
皈依者
reload()
到importlib.reload()
.
- renames¶
变化
sys.maxint
到sys.maxsize
.
- sys_exc¶
更改已弃用的
sys.exc_value
,sys.exc_type
,sys.exc_traceback
使用sys.exc_info()
.
- throw¶
修复生成器中的API更改
throw()
方法。
- tuple_params¶
删除隐式元组参数解包。此修复程序插入临时变量。
- ws_comma¶
从逗号分隔的项中删除多余的空白。此固定器是可选的。
- xreadlines¶
变化
for x in file.xreadlines()
到for x in file
.
lib2to3
-2to3的库¶
源代码: Lib/lib2to3/
3.10 版后已移除: Python 3.9将切换到PEG解析器(请参见 PEP 617 ),Python 3.10可能包含lib2to3的LL(1)解析器无法解析的新语言语法。这个 lib2to3
模块可能会在将来的Python版本中从标准库中删除。考虑第三方替代方案,如 LibCST 或 parso .
注解
这个 lib2to3
API应被认为是不稳定的,并可能在未来发生剧烈变化。