26.7. 2to3 - 自动Python 2到3代码翻译

2to3是一个Python程序,它读取Python 2.x源代码,并应用一系列修复器将其转换为有效的Python 3.x代码。标准库包含一组丰富的修复程序,它们将处理几乎所有的代码。2to3支持库lib2to3是一个灵活的和通用的库,所以可以编写自己的修复软件2to3。lib2to3也可以适用于需要自动编辑Python代码的自定义应用程序。

26.7.1. Using 2to3

2to3通常会安装Python解释器作为脚本。它也位于Python根目录的Tools/scripts目录中。

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)

它可以通过命令行中的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)

在整个翻译过程中保留评论和精确缩进。

默认情况下,2to3运行一组predefined fixers-l可以使用-f给出要运行的一组明确的修复程序。同样,-x显式禁用修复程序。以下示例仅运行importshas_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标志。请注意,只有 doctests将被重构。这也不需要模块是有效的Python。例如,doctest like reST文档中的示例也可以使用此选项重构。

-v选项允许输出有关翻译过程的更多信息。

由于一些打印语句可以解析为函数调用或语句,因此2to3不能总是读取包含打印函数的文件。当2to3检测到来自 t> __未来__ 导入 print_function编译器指令时,修改其内部语法以将print()解释为函数。此更改也可以使用-p标志手动启用。使用-p在已经转换其打印语句的代码上运行修复程序。

-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

26.7.2. Fixers

转换代码的每个步骤都封装在修复程序中。命令2to3 -l 列出它们。由于documented above,每个可以单独打开和关闭。这里更详细地描述它们。

apply

删除apply()的使用。例如apply(function, * args, ** kwargs)转换为函数(* args, ** kwargs)

asserts

Replaces deprecated unittest method names with the correct ones.

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类似,但不完全相同。

callable

Converts callable(x) to isinstance(x, collections.Callable), adding an import to collections if needed. 注意callable(x)在Python 3.2中返回,所以如果你不打算支持Python 3.1,你可以禁用这个修复软件。

dict

修复字典迭代方法。dict.iteritems() is converted to dict.items(), dict.iterkeys() to dict.keys(), and dict.itervalues() to dict.values(). 同样,dict.viewitems()dict.viewkeys()dict.viewvalues()分别转换为dict.items()dict.keys()dict.values()It also wraps existing usages of dict.items(), dict.keys(), and dict.values() in a call to list.

except

Converts except X, T to except X as T.

exec

exec语句转换为exec()函数。

execfile

删除execfile()的使用。execfile()的参数包含在open()compile()exec()

exitfunc

更改sys.exitfunc的分配以使用atexit模块。

filter

list调用中使用filter()使用。

funcattrs

修复已重命名的函数属性。例如,my_function.func_closure将转换为my_function.__closure__

future

__未来__ 导入 new_feature语句中删除

getcwdu

os.getcwdu()重命名为os.getcwd()

has_key

dict中将dict.has_key(key)更改为

idioms

这个可选的修复程序执行几个转换,使Python代码更惯用。Type comparisons like type(x) is SomeClass and type(x) == SomeClass are converted to isinstance(x, SomeClass). ,而 1成为,而 此修复程序还尝试在适当的地方使用sorted()例如,这个块

L = list(some_iterable)
L.sort()

改为

L = sorted(some_iterable)
import

检测兄弟导入,并将其转换为相对导入。

imports

处理标准库中的模块重命名。

imports2

处理标准库中的其他模块重命名。它仅与imports固定程序分开,因为存在技术限制。

input

input(prompt)转换为eval(input(prompt))

intern

intern()转换为sys.intern()

isinstance

修复isinstance()的第二个参数中的重复类型。例如,isinstance(x, (int, int))被转换为isinstance(x, (int))

itertools_imports

删除itertools.ifilter()itertools.izip()itertools.imap()的导入。导入itertools.ifilterfalse()也会更改为itertools.filterfalse()

itertools

itertools.ifilter()itertools.izip()itertools.imap()的用法更改为其内建等效项。itertools.ifilterfalse()更改为itertools.filterfalse()

long

long重命名为int

map

list调用中换行map()它还会更改映射(无, x)list(x)使用 future_builtins 导入 地图禁用此修复程序。

metaclass

Converts the old metaclass syntax (__metaclass__ = Meta in the class body) to the new (class X(metaclass=Meta)).

methodattrs

修复旧方法属性名称。例如,meth.im_func被转换为meth.__func__

ne

将旧的不等式语法<>转换为!=

next

将迭代器的next()方法转换为next()函数。它还将next()方法重命名为__next__()

nonzero

__nonzero__()重命名为__bool__()

numliterals

将八进制字面值转换为新的语法。

operator

将对operator模块中各种函数的调用转换为其他函数,但等价的函数调用。需要时,添加适当的import语句,例如import 容器进行以下映射:

operator.isCallable(obj)hasattr(obj, '__ call __')
operator.sequenceIncludes(obj)operator.contains(obj)
operator.isSequenceType(obj)isinstance(obj, 容器。序列)
operator.isMappingType(obj)isinstance(obj, 容器.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

在列表推导式中添加需要的括号。For example, [x for x in 1, 2] becomes [x for x in (1, 2)].

print

print语句转换为print()函数。

raise

转换提高 E, V提高 E V)提高 E, V, / t7>到提高 E(V).with_traceback(T)如果E是元组,则翻译将不正确,因为替换元组在3.0中已除去异常。

raw_input

raw_input()转换为input()

reduce

处理reduce()functools.reduce()的移动。

reload

reload()转换为imp.reload()

renames

sys.maxint更改为sys.maxsize

repr

repr()函数替换backtick repr。

set_literal

用set字面值替换set构造函数的使用。此修订包是可选的。

standarderror

StandardError重命名为Exception

sys_exc

更改已弃用的sys.exc_valuesys.exc_typesys.exc_traceback以使用sys.exc_info()

throw

修复生成器的throw()方法中的API更改。

tuple_params

删除隐式元组参数分拆。此修订包插入临时变量。

types

修复因删除types模块中的某些成员而导致的代码。

unicode

unicode重命名为str

urllib

处理urlliburllib2的重命名为urllib包。

ws_comma

从逗号分隔的项目中删除多余的空格。此修订包是可选的。

xrange

xrange()重新命名为range()并用list包装现有range()

xreadlines

Changes for x in file.xreadlines() to for x in file.

zip

list调用中封装zip()使用。当出现 future_builtins import zip时,

26.7.3. lib2to3 - 2to3的库

源代码: Lib / lib2to3 /

注意

lib2to3 API应被视为不稳定,并且将来可能会发生巨大变化。