2to3
是Python官方提供的用于将Python 2代码转换为Python 3代码的工具。它能够自动检测Python 2代码中的语法和库差异,并尝试进行相应的转换。
2to3
是Python的一部分,因此在安装Python时它会自动安装,如果一些版本的python没有自带2to3
工具,可以使用pip命令安装:
pip install 2to3
要运行 2to3,你可以在命令行中输入:
2to3.exe --help
$ 2to3.exe --help
用法:2to3 [选项] 文件|目录...
选项:
-h, --help 显示此帮助信息并退出
-d, --doctests_only 仅修复文档测试
-f FIX, --fix=FIX 每个 FIX 指定一个转换;默认:全部
-j PROCESSES, --processes=PROCESSES
并行运行 2to3
-x NOFIX, --nofix=NOFIX
阻止运行某个转换
-l, --list-fixes 列出可用的转换
-p, --print-function 修改语法以使 print() 成为一个函数
-e, --exec-function 修改语法以使 exec() 成为一个函数
-v, --verbose 更详细的日志记录
--no-diffs 不显示重构的差异
-w, --write 写回修改后的文件
-n, --nobackups 不为修改后的文件写备份
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
将输出文件放在此目录中,而不是覆盖输入文件。需要 -n。
-W, --write-unchanged-files
即使没有必要进行更改,也写入文件(与 --output-dir 一起使用很有用);隐含 -w。
--add-suffix=ADD_SUFFIX
在所有输出文件名后附加此字符串。如果非空,需要 -n。 例如:--add-suffix='3' 将生成
-h, --help
:
2to3 --help
-d, --doctests_only
:
2to3 -d your_code.py
-f FIX, --fix=FIX
:
2to3 -f all your_code.py
-j PROCESSES, --processes=PROCESSES
:
2to3 -j 4 your_code.py
-x NOFIX, --nofix=NOFIX
:
2to3 -x range your_code.py
-l, --list-fixes
:
2to3 -l
-p, --print-function
:
print()
成为一个函数。在Python 3中,print
语句被替换为了 print()
函数。2to3 -p your_code.py
-e, --exec-function
:
exec()
成为一个函数。在Python 3中,exec
语句被替换为了 exec()
函数。2to3 -e your_code.py
-v, --verbose
:
2to3 -v your_code.py
--no-diffs
:
2to3 --no-diffs your_code.py
-w, --write
:
2to3 -w your_code.py
-n, --nobackups
:
2to3 -n your_code.py
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
:
-n
选项一起使用。2to3 -o converted_code -n your_code.py
-W, --write-unchanged-files
:
--output-dir
选项时非常有用,会确保所有文件都被写入。2to3 -W -o converted_code -n your_code.py
--add-suffix=ADD_SUFFIX
:
-n
选项一起使用。2to3 --add-suffix='.bak' -n your_code.py
只提示,不修改原脚本:
$ 2to3.exe -j 4 .
RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
--- .\main.py (original)
+++ .\main.py (refactored)
@@ -1 +1 @@
-print "This is ingress of the project"
+print("This is ingress of the project")
--- .\apps\urls.py (original)
+++ .\apps\urls.py (refactored)
@@ -1 +1 @@
-print "this is the url file"
+print("this is the url file")
RefactoringTool: No files need to be modified.
直接修改原脚本,同时会对原脚本做备份 -w:
$ 2to3.exe -w .
RefactoringTool: Skipping optional fixer: buffer
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: set_literal
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored .\main.py
RefactoringTool: Refactored .\apps\urls.py
RefactoringTool: Files that were modified:
RefactoringTool: .\main.py
RefactoringTool: .\apps\urls.py
--- .\main.py (original)
+++ .\main.py (refactored)
@@ -1 +1 @@
-print "This is ingress of the project"
+print("This is ingress of the project")
--- .\apps\urls.py (original)
+++ .\apps\urls.py (refactored)
@@ -1 +1 @@
-print "this is the url file"
+print("this is the url file")
一般情况下,对于大项目应该并发的去转换,并且应用所有过滤规则,然后将原文件备份以供参考:
2to3.exe -j 4 -f all -w .
2to3 工具是一个非常有用的工具,但也有一些缺陷和注意事项:
不能处理所有情况:
可能会引入错误:
需要人工审查:
不一定能保留所有的原始注释和格式:
对第三方库的支持有限:
可能会产生大量的转换结果:
可能会导致性能下降:
不适用于所有项目:
总的来说,2to3是一个很有用的工具,可以帮助自动化大部分的Python 2到Python 3的迁移工作,但需要谨慎使用,同时在转换后进行仔细的代码审查以确保正确性。在处理复杂或特殊情况时,可能需要结合手动调整和其他工具来完成迁移工作。
future
是一个用于帮助在 Python 2 代码中使用 Python 3 的特性的库。它提供了一组可以让 Python 2 代码更容易向 Python 3 迁移的工具。
可以使用pip命令安装该工具:
pip install future
以下是 future
库的一些主要特点和功能:
兼容性:
future
库可以让你在 Python 2 中使用一些 Python 3 的特性,从而逐步实现向 Python 3 的平滑过渡。提供兼容模块:
future
提供了一系列的模块,例如 __future__
、builtins
等,可以让你在 Python 2 中使用 Python 3 的一些内置函数、语法等。简化代码:
future
提供的模块,你可以更容易地编写符合 Python 3 标准的代码,而不必担心在 Python 2 中的兼容性问题。提供一些辅助函数和工具:
future
还提供了一些辅助函数,用于处理一些常见的迁移问题,例如处理文本编码等。支持通过命令行工具进行代码转换:
futurize
是 future
库提供的一个命令行工具,可以帮助你批量地将 Python 2 代码转换为兼容 Python 3 的代码。
例如,可以通过以下命令将一个目录下的 Python 2 代码转换为 Python 3:
futurize -f all your_code.py
提供配置选项:
总的来说,future
是一个非常实用的库,可以帮助你在 Python 2 中逐步采用 Python 3 的特性,从而为将来迁移到 Python 3 打下基础。但需要注意,虽然它可以简化许多工作,但并不是所有的代码都可以通过 future
完全自动转换,可能还需要手动进行一些调整。
$ futurize --help
Usage: futurize [options] file|dir ...
Options:
-h, --help show this help message and exit
-V, --version Report the version number of futurize
-a, --all-imports Add all __future__ and future imports to each module
-1, --stage1 Modernize Python 2 code only; no compatibility with
Python 3 (or dependency on ``future``)
-2, --stage2 Take modernized (stage1) code and add a dependency on
``future`` to provide Py3 compatibility.
-0, --both-stages Apply both stages 1 and 2
-u, --unicode-literals
Add ``from __future__ import unicode_literals`` to
implicitly convert all unadorned string literals ''
into unicode strings
-f FIX, --fix=FIX Each FIX specifies a transformation; default: all.
Either use '-f division -f metaclass' etc. or use the
fully-qualified module name: '-f
lib2to3.fixes.fix_types -f
libfuturize.fixes.fix_unicode_keep_u'
-j PROCESSES, --processes=PROCESSES
Run 2to3 concurrently
-x NOFIX, --nofix=NOFIX
Prevent a fixer from being run.
-l, --list-fixes List available transformations
-p, --print-function Modify the grammar so that print() is a function
-v, --verbose More verbose logging
--no-diffs Don't show diffs of the refactoring
-w, --write Write back modified files
-n, --nobackups Don't write backups for modified files.
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
Put output files in this directory instead of
overwriting the input files. Requires -n. For Python
>= 2.7 only.
-W, --write-unchanged-files
Also write files even if no changes were required
(useful with --output-dir); implies -w.
--add-suffix=ADD_SUFFIX
Append this string to all output filenames. Requires
-n if non-empty. For Python >= 2.7 only.ex: --add-
suffix='3' will generate .py3 files.
汉化:
$ futurize --help
用法: futurize [选项] 文件|目录 ...
选项:
-h, --help 显示此帮助信息并退出
-V, --version 报告 futurize 的版本号
-a, --all-imports 向每个模块添加所有的 __future__ 和 future 导入
-1, --stage1 仅现代化 Python 2 代码;不与 Python 3 兼容(或依赖于“future”)
-2, --stage2 获取现代化(stage1)代码并添加对“future”的依赖以提供 Py3 兼容性。
-0, --both-stages 应用阶段1和阶段2
-u, --unicode-literals
添加“from __future__ import unicode_literals”以隐式将所有未装饰的字符串文字 '' 转换为 Unicode 字符串
-f FIX, --fix=FIX 每个 FIX 指定一个转换;默认:全部。
要么使用 '-f division -f metaclass' 等,或者使用完全限定的模块名:'-f
lib2to3.fixes.fix_types -f
libfuturize.fixes.fix_unicode_keep_u'
-j PROCESSES, --processes=PROCESSES
并行运行 2to3
-x NOFIX, --nofix=NOFIX
阻止运行某个转换。
-l, --list-fixes 列出可用的转换
-p, --print-function 修改语法以使 print() 成为一个函数
-v, --verbose 更详细的日志记录
--no-diffs 不显示重构的差异
-w, --write 写回修改后的文件
-n, --nobackups 不为修改后的文件写备份。
-o OUTPUT_DIR, --output-dir=OUTPUT_DIR
将输出文件放在此目录中,而不是覆盖输入文件。需要 -n。仅适用于 Python >= 2.7。
-W, --write-unchanged-files
即使没有必要进行更改,也写入文件(与 --output-dir 一起使用很有用);隐含 -w。
--add-suffix=ADD_SUFFIX
在所有输出文件名后附加此字符串。如果非空,需要 -n。仅适用于 Python >= 2.7。例如:--add-
suffix='3' 将生成 .py3 文件。
futurize的代码转换方法有第1阶段和第2阶段。
stage1:
在不影响Python2系统环境的范围内执行代码转换。因此,stage1中转换后的代码可能无法在Python3环境中工作。 stage1的目的是在与Python2兼容的范围内执行代码转换,这是完全更改Python3系列代码的第一步。通过将stage1夹在中间,可以降低一次转换代码的风险。
在stage1中,使用__future__模块,以便甚至可以在2系列环境中实现Python 3系列中与2系列不兼容的功能。不要添加将来的模块。
stage2:
基本使用:
预览stage1中更改的部分(不写入)。
$ futurize.exe --stage1 .
RefactoringTool: Skipping optional fixer: idioms
RefactoringTool: Skipping optional fixer: ws_comma
RefactoringTool: Refactored .\main.py
RefactoringTool: Refactored .\apps\urls.py
RefactoringTool: Files that need to be modified:
RefactoringTool: .\main.py
RefactoringTool: .\apps\urls.py
--- .\main.py (original)
+++ .\main.py (refactored)
@@ -1 +1,2 @@
-print "This is ingress of the project"
+from __future__ import print_function
+print("This is ingress of the project")
--- .\apps\urls.py (original)
+++ .\apps\urls.py (refactored)
@@ -1 +1,2 @@
-print "this is the url file"
+from __future__ import print_function
+print("this is the url file")
重写代码,并生成备份文件
futurize.exe -0 -w -f all .
python-modernize
是一个用于将 Python 2 代码现代化以兼容 Python 3 的工具。它提供了一组自动化工具,可以帮助将 Python 2 代码转换成符合 Python 3 标准的形式。
可以使用pip命令安装:
pip install modernize
以下是 python-modernize
的一些主要特点和功能:
自动转换:
python-modernize
提供了一系列的 fixers(转换器),可以自动将 Python 2 代码转换为兼容 Python 3 的形式。向后兼容:
提供多个 fixers:
python-modernize
包含许多 fixers,可以用于解决各种不同的转换问题,例如将 print
语句转换为 print()
函数、将除法行为从整数转换为浮点数等。支持多个转换阶段:
提供详细的帮助文档:
python-modernize
提供了丰富的文档,可以帮助你了解如何正确地使用工具。支持通过命令行工具进行代码转换:
你可以使用命令行工具来批量转换 Python 2 代码为兼容 Python 3 的形式。
例如,可以通过以下命令将一个目录下的 Python 2 代码转换为 Python 3:
modernize -f future your_code.py
可定制性:
提供备份功能:
python-modernize
可以为转换后的代码创建备份,以便在需要时进行恢复。$ modernize.exe --help
Python _ _
_ __ ___ __| |___ _ _ _ _ (_)______
| ' \/ _ \/ _` / -_) '_| ' \| |_ / -_)
|_|_|_\___/\__,_\___|_| |_||_|_/__\___| 0.8.0
Usage: modernize [options] file|dir ...
Options:
--version show program's version number and exit
-h, --help show this help message and exit
-v, --verbose Show more verbose logging.
--no-diffs Don't show diffs of the refactoring.
-l, --list-fixes List standard transformations.
-d, --doctests_only Fix up doctests only.
-f FIX, --fix=FIX Each FIX specifies a transformation; '-f default'
includes default fixers.
--fixers-here Add current working directory to python path (so
fixers can be found)
-j PROCESSES, --processes=PROCESSES
Run fissix concurrently.
-x NOFIX, --nofix=NOFIX
Prevent a fixer from being run.
-p, --print-function Modify the grammar so that print() is a function.
-w, --write Write back modified files.
-n, --nobackups Don't write backups for modified files.
--six-unicode Wrap unicode literals in six.u().
--future-unicode Use 'from __future__ import unicode_literals'(only
useful for Python 2.6+).
--no-six Exclude fixes that depend on the six package.
--enforce Returns non-zero exit code if any fixers had to be
applied. Useful for enforcing Python 3 compatibility.
汉化:
$ modernize.exe --help
Python _ _
_ __ ___ __| |___ _ _ _ _ (_)______
| ' \/ _ \/ _` / -_) '_| ' \| |_ / -_)
|_|_|_\___/\__,_\___|_| |_||_|_/__\___| 0.8.0
用法: modernize [选项] 文件|目录 ...
选项:
--version 显示程序版本号并退出
-h, --help 显示此帮助信息并退出
-v, --verbose 显示更详细的日志记录。
--no-diffs 不显示重构的差异。
-l, --list-fixes 列出标准的转换。
-d, --doctests_only 仅修复文档测试。
-f FIX, --fix=FIX 每个 FIX 指定一个转换;'-f default' 包括默认的转换器。
--fixers-here 将当前工作目录添加到 Python 路径中(以便找到转换器)。
-j PROCESSES, --processes=PROCESSES
并行运行 fissix。
-x NOFIX, --nofix=NOFIX
阻止运行某个转换。
-p, --print-function 修改语法以使 print() 成为一个函数。
-w, --write 写回修改后的文件。
-n, --nobackups 不为修改后的文件写备份。
--six-unicode 将 Unicode 文字字面值包装在 six.u() 中。
--future-unicode 使用 'from __future__ import unicode_literals'(仅适用于 Python 2.6+)。
--no-six 排除依赖于 six 包的转换。
--enforce 如果需要应用任何转换,则返回非零退出代码。用于强制执行 Python 3 兼容性。
当你使用 modernize.exe
工具时,你可以按照以下示例来执行相应的转换操作。
modernize.exe --version
modernize.exe --help
modernize.exe -l
modernize.exe -d your_code.py
modernize.exe -f default your_code.py
modernize.exe -j 4 your_code.py
division
转换):modernize.exe -x division your_code.py
print()
成为一个函数:modernize.exe -p your_code.py
modernize.exe -w your_code.py
modernize.exe -n your_code.py
six.u()
中:modernize.exe --six-unicode your_code.py
from __future__ import unicode_literals
(仅适用于 Python 2.6+):modernize.exe --future-unicode your_code.py
six
包的转换:modernize.exe --no-six your_code.py
modernize.exe --enforce your_code.py
略
A tool (and pre-commit hook) to automatically upgrade syntax for newer versions of the language.
pip install pyupgrade
$ pyupgrade.exe --help
usage: pyupgrade [-h] [--exit-zero-even-if-changed] [--keep-percent-format]
[--keep-mock] [--keep-runtime-typing] [--py3-plus]
[--py36-plus] [--py37-plus] [--py38-plus] [--py39-plus]
[--py310-plus] [--py311-plus]
[filenames ...]
positional arguments:
filenames
options:
-h, --help show this help message and exit
--exit-zero-even-if-changed
--keep-percent-format
--keep-mock
--keep-runtime-typing
--py3-plus, --py3-only
--py36-plus
--py37-plus
--py38-plus
--py39-plus
--py310-plus
--py311-plus
汉…化:
$ pyupgrade.exe --help
用法: pyupgrade [-h] [--exit-zero-even-if-changed] [--keep-percent-format]
[--keep-mock] [--keep-runtime-typing] [--py3-plus]
[--py36-plus] [--py37-plus] [--py38-plus] [--py39-plus]
[--py310-plus] [--py311-plus]
[文件名 ...]
位置参数:
文件名
选项:
-h, --help 显示此帮助信息并退出
--exit-zero-even-if-changed
--keep-percent-format
--keep-mock
--keep-runtime-typing
--py3-plus, --py3-only
--py36-plus
--py37-plus
--py38-plus
--py39-plus
--py310-plus
--py311-plus
转换单个文件:
使用以下命令可以将单个 Python 文件转换为 Python 3 兼容形式:
pyupgrade your_code.py
这会将 your_code.py
中的 Python 2 代码转换为 Python 3 兼容的形式。
转换整个目录:
如果你想批量转换一个目录下的所有 Python 文件,可以使用类似以下的命令:
pyupgrade your_directory/
这将会逐个转换目录中的所有 Python 文件。
保留百分号格式化字符串:
如果你想保留百分号格式化字符串(如 %s
)而不转换为 f-strings,可以使用 --keep-percent-format
选项:
pyupgrade --keep-percent-format your_code.py
保留 mock 模块:
如果你使用了 mock
模块,可以使用 --keep-mock
选项来保留该模块:
pyupgrade --keep-mock your_code.py
保留运行时类型提示:
如果你想保留运行时类型提示(如 # type: ignore
),可以使用 --keep-runtime-typing
选项:
pyupgrade --keep-runtime-typing your_code.py
仅转换到 Python 3:
默认情况下,pyupgrade
将代码转换为适用于所有 Python 3 版本的形式。如果你想只将代码转换为 Python 3,可以使用 --py3-only
选项:
pyupgrade --py3-only your_code.py
只转换到特定 Python 3 版本:
你可以使用相应的选项(如 --py36-plus
、--py37-plus
等)来将代码转换为特定版本的 Python 3 兼容形式。
例如,要将代码转换为 Python 3.6 兼容形式,可以使用:
pyupgrade --py36-plus your_code.py
同样的方式适用于其他版本,如 Python 3.7、Python 3.8 等。
设置退出代码:
默认情况下,如果发生了转换,pyupgrade
将返回非零退出代码。你可以使用 --exit-zero-even-if-changed
选项来始终返回零退出代码。
pyupgrade --exit-zero-even-if-changed your_code.py
将python2转为python3.11:
print "This is ingress of the project"
class C(Base):
def f(self):
super(C, self).f()
import functools
@functools.lru_cache()
def expensive():
pass
执行pyupgrade --py3-plus .\main.py
令我疑惑的是,并没有任何事情发生!!
选择哪个工具来进行从 Python 2 到 Python 3 的迁移取决于你的项目特定需求以及你个人的偏好。以下是一些常用的迁移工具的特点和适用场景:
2to3:
futurize:
future
依赖以实现完全的 Python 3 兼容(阶段 2)。modernize:
pyupgrade: