On this page
25.4. 2 to3-自动 Python 2 到 3 代码翻译
2 to3 是一个 Python 程序,它读取 Python 2.x 源代码并应用一系列* fixers *将其转换为有效的 Python 3.x 代码。标准库包含一组丰富的修复程序,可以处理几乎所有代码。但是 2to3 支持库lib2to3是一个灵活且通用的库,因此可以为 2to3 编写自己的修复程序。 lib2to3还可以适用于需要自动编辑 Python 代码的自定义应用程序。
25.4.1. 使用 2to3
2 to3 通常会与 Python 解释器一起作为脚本安装。它也位于 Python 根目录的Tools/scripts
目录中。
2 to3 的基本参数是要转换的文件或目录的列表。对于 Python 源,递归遍历目录。
这是一个示例 Python 2.x 源文件example.py
:
def greet(name):
print "Hello, {0}!".format(name)
print "What's your name?"
name = raw_input()
greet(name)
可以在命令行上pass 2to3 将其转换为 Python 3.x 代码:
$ 2to3 example.py
将打印与原始源文件的差异。 2to3 还可以将所需的修改直接写回到源文件。 (除非也给出了-n
,否则将备份原始文件.)使用-w
标志启用回写更改:
$ 2to3 -w example.py
转换后,example.py
如下所示:
def greet(name):
print("Hello, {0}!".format(name))
print("What's your name?")
name = input()
greet(name)
Comments 和确切的缩进将在整个翻译过程中保留。
默认情况下,2to3 运行一组predefined fixers。 -l
标志列出了所有可用的修复程序。可以使用-f
给出一组明确的修复程序。同样,-x
明确禁用修复程序。以下示例仅运行imports
和has_key
修复程序:
$ 2to3 -f imports -f has_key example.py
此命令运行除apply
修复程序之外的所有修复程序:
$ 2to3 -x apply example.py
有些修复程序是* explicit *,这意味着它们默认情况下不会运行,必须在命令行中列出才能运行。在这里,除了默认的修复程序外,还运行idioms
修复程序:
$ 2to3 -f all -f idioms example.py
请注意,传递all
如何启用所有默认修复程序。
有时 2to3 会在您的源代码中找到一个需要更改的位置,但是 2to3 无法自动修复。在这种情况下,2to3 将在差异文件下方显示警告。您应该解决该警告,以获取兼容的 3.x 代码。
2 to3 也可以重构 doctest。要启用此模式,请使用-d
标志。注意,* only * doctests 将被重构。这也不需要模块是有效的 Python。例如,reST 文档中的 doctest 之类的示例也可以使用此选项进行重构。
-v
选项可输出有关翻译过程的更多信息。
由于某些打印语句可以解析为函数调用或语句,因此 2to3 不能始终读取包含打印Function的文件。当 2to3 检测到from __future__ import print_function
编译器指令的存在时,它将修改其内部语法以将print()解释为函数。也可以使用-p
标志手动启用此更改。使用-p
在已转换其打印语句的代码上运行修复程序。
-o
或--output-dir
选项允许指定要写入的已处理输出文件的备用目录。使用此标记时需要-n
标志,因为不覆盖 Importing 文件时,备份文件没有意义。
版本 2.7.3 中的新增Function:添加了-o
选项。
-W
或--write-unchanged-files
标志告诉 2to3 始终写入输出文件,即使不需要更改文件也是如此。这对于-o
最为有用,因此可以将整个 Python 源树复制并从一个目录复制到另一个目录。该选项暗含-w
标志,因为否则它没有意义。
版本 2.7.3 中的新Function:添加了-W
标志。
--add-suffix
选项指定要附加到所有输出文件名的字符串。指定此名称时需要-n
标志,因为写入不同的文件名时不需要备份。例:
$ 2to3 -n -W --add-suffix=3 example.py
将导致转换后的名为example.py3
的文件被写入。
版本 2.7.3 中的新增Function:添加了--add-suffix
选项。
要将整个项目从一个目录树转换为另一种使用:
$ 2to3 --output-dir=python3-version/mycode -W -n python2-version/mycode
25.4.2. Fixers
转换代码的每个步骤都封装在修复程序中。命令2to3 -l
列出了它们。作为documented above,每个都可以单独打开和关闭。它们在这里有更详细的描述。
apply
- 删除apply()的用法。例如
apply(function, *args, **kwargs)
转换为function(*args, **kwargs)
。
- 删除apply()的用法。例如
asserts
- 用正确的名称替换不推荐使用的unittest方法名称。
From | To |
---|---|
failUnlessEqual(a, b) |
assertEqual(a, b) |
assertEquals(a, b) |
assertEqual(a, b) |
failIfEqual(a, b) |
assertNotEqual(a, b) |
assertNotEquals(a, b) |
assertNotEqual(a, b) |
failUnless(a) |
assertTrue(a) |
assert_(a) |
assertTrue(a) |
failIf(a) |
assertFalse(a) |
failUnlessRaises(exc, cal) |
assertRaises(exc, cal) |
failUnlessAlmostEqual(a, b) |
assertAlmostEqual(a, b) |
assertAlmostEquals(a, b) |
assertAlmostEqual(a, b) |
failIfAlmostEqual(a, b) |
assertNotAlmostEqual(a, b) |
assertNotAlmostEquals(a, b) |
assertNotAlmostEqual(a, b) |
basestring
- 将basestring转换为str。
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()。它还在对
list
的调用中包装了dict.items(),dict.keys()和dict.values()的现有用法。
- 修复字典迭代方法。 dict.iteritems()转换为dict.items(),dict.iterkeys()转换为dict.keys(),dict.itervalues()转换为dict.values()。类似地,dict.viewitems(),dict.viewkeys()和dict.viewvalues()分别转换为dict.items(),dict.keys()和dict.values()。它还在对
except
- 将
except X, T
转换为except X as T
。
- 将
exec
- 将exec语句转换为
exec()
函数。
- 将exec语句转换为
execfile
- 删除execfile()的用法。 execfile()的参数包装在对open(),compile()和
exec()
的调用中。
- 删除execfile()的用法。 execfile()的参数包装在对open(),compile()和
exitfunc
- 将sys.exitfunc的分配更改为使用atexit模块。
filter
- 将filter()用法包装在
list
通话中。
- 将filter()用法包装在
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
。此修复程序还try在适当的地方使用sorted()。例如,这个方块
- 这个可选的修复程序执行了一些转换,使 Python 代码更加惯用。诸如
L = list(some_iterable)
L.sort()
更改为
L = sorted(some_iterable)
import
- 检测同级导入并将其转换为相对导入。
imports
- 处理模块在标准库中的重命名。
imports2
- 处理标准库中的其他模块重命名。仅由于技术限制,它与imports修复程序分开。
input
- 将
input(prompt)
转换为eval(input(prompt))
。
- 将
intern
- 将intern()转换为
sys.intern()
。
- 将intern()转换为
isinstance
- 修复了isinstance()的第二个参数中的重复类型。例如,
isinstance(x, (int, int))
转换为isinstance(x, (int))
。
- 修复了isinstance()的第二个参数中的重复类型。例如,
itertools_imports
- 删除itertools.ifilter(),itertools.izip()和itertools.imap()的导入。 itertools.ifilterfalse()的导入也更改为
itertools.filterfalse()
。
- 删除itertools.ifilter(),itertools.izip()和itertools.imap()的导入。 itertools.ifilterfalse()的导入也更改为
itertools
- 将itertools.ifilter(),itertools.izip()和itertools.imap()的用法更改为它们的内置等效项。 itertools.ifilterfalse()更改为
itertools.filterfalse()
。
- 将itertools.ifilter(),itertools.izip()和itertools.imap()的用法更改为它们的内置等效项。 itertools.ifilterfalse()更改为
long
map
- 将map()包裹在
list
通话中。还将map(None, x)
更改为list(x)
。使用from future_builtins import map
禁用此修复程序。
- 将map()包裹在
metaclass
- 将旧的元类语法(类主体中的
__metaclass__ = Meta
)转换为新的元语法(class X(metaclass=Meta)
)。
- 将旧的元类语法(类主体中的
methodattrs
- 修复旧的方法属性名称。例如,
meth.im_func
转换为meth.__func__
。
- 修复旧的方法属性名称。例如,
ne
- 将旧的不等语法
<>
转换为!=
。
- 将旧的不等语法
next
nonzero
- 将nonzero()重命名为
__bool__()
。
- 将nonzero()重命名为
numliterals
- 将八进制 Literals 转换为新语法。
paren
- 在列表推导中需要的地方添加额外的括号。例如,
[x for x in 1, 2]
变为[x for x in (1, 2)]
。
- 在列表推导中需要的地方添加额外的括号。例如,
print
raise
- 将
raise E, V
转换为raise E(V)
,并将raise E, V, T
转换为raise E(V).with_traceback(T)
。如果E
是一个 Tuples,则转换将是不正确的,因为在 Python 3 中已删除了用 Tuples 代替异常的方法。
- 将
raw_input
- 将raw_input()转换为input()。
reduce
- 处理reduce()到functools.reduce()的移动。
renames
repr
- 用repr()函数替换反引号 repr。
set_literal
- 用设置的 Literals 替换set构造函数的使用。该修复程序是可选的。
standarderror
- 将StandardError重命名为Exception。
sys_exc
throw
- 修复了生成器的
throw()
方法中的 API 更改。
- 修复了生成器的
tuple_params
- 删除隐式 Tuples 参数解包。此修复程序插入临时变量。
types
- 修复了由于删除types模块中的某些成员而导致的代码损坏。
unicode
urllib
ws_comma
- 从逗号分隔的项目中删除多余的空格。该修复程序是可选的。
xrange
xreadlines
- 将
for x in file.xreadlines()
更改为for x in file
。
- 将
zip
- 将zip()用法包装在
list
通话中。出现from future_builtins import zip
时将其禁用。
- 将zip()用法包装在
25.4.3. lib2to3-2to3 的库
Note
lib2to3 API 应该被认为是不稳定的,将来可能会发生巨大变化。