Python 每个新版本中的标准库会新增一些更便捷的功能,但自己在写库时为了兼容旧版本 Python 就不会使用那些最近新增的功能。例如用 pathlib 删除一个文件,无论文件存在与否:
from pathlib import Path
# 写法一 (Python 3.8+)
Path('file').unlink(missing_ok=True)
# 写法二
try:
Path('file').unlink()
except FileNotFoundError:
pass
因为 missing_ok
是 Python 3.8 时新增的选项,所以如果要兼容 Python 3.8 以前的版本,就会用写法二。
在最初库写成一段时间后,可能会决定放弃支持一些 Python 的旧版本。在这个例子里,如果我想放弃对 Python 3.7 的支持,如果有工具能找出现有代码中的可能为写法二的部分,提示我考虑写法一,那对维护工作就省心多了。那有这种代码检查吗?
题外话:分享一个解决我这个问题相反问题的工具:vermin。可以用来检查一个 Python 文件 /包所需要的最低 Python 版本。
1
janxin 2021-10-24 08:54:39 +08:00
反过来的思路就比较复杂了,应该没具体的工具,另外一个是如果不是性能有提升或者代码简洁性提升的化这种改写并无必要,毕竟兼容老版本的代码不是全部不能用。追新也是一种代码维护成本的。
其实有个更简单的方案:利用特定注释可以快速检索到内容即可 比如 # TODO:升级到 3.8+新写法 这样只需要一个现成的编辑器 /IDE 插件就好了,比如 VSCode 的 Better Comments |
2
Pagliacii 2021-10-24 08:55:33 +08:00
|
3
Trim21 2021-10-24 09:44:19 +08:00 via Android 1
|
4
Contextualist OP @janxin 哈哈是,那些我留意到的兼容代码我确实有写注释。不过对于足够老的代码就行不通了,比如说我写第一版代码的时候 Python 的最新版本是 3.7 ,我是不能预知 Python 3.9 的新功能的。或许代码老到一定程度就是维持现状或整体重构两条路了。
@Pagliacii 这个似乎是写给用我写的库的下游用户看的。不过 Python 标准库确实也会给 DeprecationWarning 。 @Trim21 好东西👍,试用了一下,这个似乎只是志在覆盖那些 100% 确定可以改写的代码(所以甚至没给只检测不修改文件的 dryrun 选项),而且大多数是语法的规则,像我提到的那种需要猜测代码意图的复杂情况可能还是比较难实现。不过对那些需要大面积改写的老代码做初筛还是很好用的。 |
5
efaun 2021-10-24 14:20:48 +08:00
|
6
Karonheaven 2021-10-25 10:07:20 +08:00
@Contextualist 我有一个脑洞,但没有进行实际测试,不知道是否可行:设置一个版本例如 3.8 ,通过 PyCharm 或者 VSCode 检查出所有不兼容代码(这些代码一般都是>3.8 的 feature ),手动检查其他未报错的代码(兼容代码都在这里面),算是一个缩小范围的方式
不过这种方式还是有缺陷,例如没法 debug 等 |
7
julyclyde 2021-10-25 11:20:30 +08:00
作为库作者的话,可以在最后加一个**kwargs
作为用户,我觉得你犯不着去兼容旧的 python |
8
lisongeee 2021-10-25 11:37:20 +08:00
python 有类似 js 的 babel 这样的 polyfill 工具吗?
|
9
Contextualist OP @lisongeee 就我所知应该是没有一站式解决方案的(有过像 github.com/nvbn/py-backwards 这样的尝试,但没有持续更新)
在 Python 社区里更常见 backport package 这种零散的方式,比如自带的 __future__, 而在 PyPI 里可以找到把 contextlib, contextvars, data classes, 甚至 f-string 等新版本功能带到旧版本的包。 |