从 Python 2 迁移到 Python 3 实战(一):pyupgrade

从这篇开始我会不定期写一些在实际工作中把项目代码从Python2.7迁移到最新的Python 3.7的经验。

这篇先介绍pyupgrade - 一个修改代码中Python 2语法到最新版本写法的工具,同时它还可以作为pre-commit钩子,可以在代码提交或者push时拒绝引入旧的用法。

为什么需要这么一个工具呢?3个理由:

  1. 替换代码中旧版本Python的用法。例如  '%s %s'%(a,b)这种百分号的字符串格式化写法

  2. 替换成Python 3的新语法。例如在Python 3中  super 不再需要传递self、字符串格式化在Python 3.6及以后可以直接用f-strings

  3. 迁移后不再需要支持Python2,所以应该去掉six模块的相关使用,直接用Python3的代码写才是正途。

我日常维护的项目中Python代码都在几千到上百万行级别,可以设想一下,如果人工来做代码替换将是一个极为浩大的工程。

在现有的Python世界,过去只有lib2to3模块和其衍生品(之后我会专门讲),但是效果有限,pyupgrade是一个很好的补充,我们来了解一下它都实现了那些功能

集合

左面是替换前的代码,后面井号后的注释部分是替换后的效果。set相关的部分算是统一用法,并不是左面的写法在Python3已经不可用。

字典解析

同上,属于统一用法

扫描二维码关注公众号,回复: 6221416 查看本文章

Python2.7+ Format说明符

从Python2.7开始,不再强制指定索引

使用str.format替代printf风格的字符串format写法

后面的是Python2.7推荐的写法。但是可以传入 --keep-percent-format 忽略这类修改。

Unicode literals

在Python3中,u'foo'其实已经是字符串的'foo',默认是不会修改这个类型数据的,除非传入 --py3-plus 或者 --py36-plus :

Invalid escape sequences

现在flake8已经会检查出这个类型错误(W605):

is /  isnot

is / isnot 从Python3.8开始会抛出SyntaxWarning错误,应该使用 == / != 替代:

pyupgrade会做如下替换:

ur 字符串文字

ur'...' 这种用法在python3已经不可用了:

数字的L后缀

在Python2数字后面会有L后缀,在Python3不再支持了:

八进制数字

这个最常见的用法是修改文件权限,在Python2中可以直接使用0755,但是Python3中这样是错误的:

pyupgrade会帮助修复这个问题:

super()

在Python3中,使用super不再需要手动传递self,传入 --py3-plus 或者 --py36-plus 会修复这个问题。

新式类

Python3 中只有新式类,传入 --py3-plus 或者 --py36-plus 会修复这个问题。

移除six相关兼容代码

当完全迁移到Python3之后,就没必要兼容Python2了,可以传入 --py3-plus 或者 --py36-plus 去掉six相关代码:

目前还有 six.add_metaclass 这个点没有实现,其他的都可以了~

f-strings

这是我最喜欢的一个功能,现在迁移到Python3都会迁到Python3.6+,所以可以直接使用 --py36-plus 参数,字符串格式化不需要用str.format,而是直接用f-strings:

后记

项目地址: https://github.com/asottile/pyupgrade

我已经在酱厂最大的几个项目之一应用了pyupgrade,已经达到生产环境使用的标准,请放心使用~

猜你喜欢

转载自blog.csdn.net/c710473510/article/details/90172164