是否有针对为了兼容的多余代码的代码检查? - V2EX
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
Contextualist
V2EX    Python

是否有针对为了兼容的多余代码的代码检查?

  •  
  •   Contextualist
    Contextualist 2021-10-24 08:14:21 +08:00 3571 次点击
    这是一个创建于 1448 天前的主题,其中的信息可能已经有所发展或是发生改变。

    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 版本。

    9 条回复    2021-10-26 05:14:17 +08:00
    janxin
        1
    janxin  
       2021-10-24 08:54:39 +08:00
    反过来的思路就比较复杂了,应该没具体的工具,另外一个是如果不是性能有提升或者代码简洁性提升的化这种改写并无必要,毕竟兼容老版本的代码不是全部不能用。追新也是一种代码维护成本的。

    其实有个更简单的方案:利用特定注释可以快速检索到内容即可

    比如
    # TODO:升级到 3.8+新写法

    这样只需要一个现成的编辑器 /IDE 插件就好了,比如 VSCode 的 Better Comments
    Pagliacii
        2
    Pagliacii  
       2021-10-24 08:55:33 +08:00
    Trim21
        3
    Trim21  
       2021-10-24 09:44:19 +08:00 via Android   1
    Contextualist
        4
    Contextualist  
    OP
       2021-10-24 11:23:30 +08:00
    @janxin 哈哈是,那些我留意到的兼容代码我确实有写注释。不过对于足够老的代码就行不通了,比如说我写第一版代码的时候 Python 的最新版本是 3.7 ,我是不能预知 Python 3.9 的新功能的。或许代码老到一定程度就是维持现状或整体重构两条路了。

    @Pagliacii 这个似乎是写给用我写的库的下游用户看的。不过 Python 标准库确实也会给 DeprecationWarning 。

    @Trim21 好东西,试用了一下,这个似乎只是志在覆盖那些 100% 确定可以改写的代码(所以甚至没给只检测不修改文件的 dryrun 选项),而且大多数是语法的规则,像我提到的那种需要猜测代码意图的复杂情况可能还是比较难实现。不过对那些需要大面积改写的老代码做初筛还是很好用的。
    efaun
        5
    efaun  
       2021-10-24 14:20:48 +08:00
    Karonheaven
        6
    Karonheaven  
       2021-10-25 10:07:20 +08:00
    @Contextualist 我有一个脑洞,但没有进行实际测试,不知道是否可行:设置一个版本例如 3.8 ,通过 PyCharm 或者 VSCode 检查出所有不兼容代码(这些代码一般都是>3.8 的 feature ),手动检查其他未报错的代码(兼容代码都在这里面),算是一个缩小范围的方式
    不过这种方式还是有缺陷,例如没法 debug 等
    julyclyde
        7
    julyclyde  
       2021-10-25 11:20:30 +08:00
    作为库作者的话,可以在最后加一个**kwargs
    作为用户,我觉得你犯不着去兼容旧的 python
    lisongeee
        8
    lisongeee  
       2021-10-25 11:37:20 +08:00
    python 有类似 js 的 babel 这样的 polyfill 工具吗?
    Contextualist
        9
    Contextualist  
    OP
       2021-10-26 05:14:17 +08:00
    @lisongeee 就我所知应该是没有一站式解决方案的(有过像 github.com/nvbn/py-backwards 这样的尝试,但没有持续更新)
    在 Python 社区里更常见 backport package 这种零散的方式,比如自带的 __future__, 而在 PyPI 里可以找到把 contextlib, contextvars, data classes, 甚至 f-string 等新版本功能带到旧版本的包。
    关于     帮助文档     自助推广系统     博客     API     FAQ     Solana     5841 人在线   最高记录 6679       Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 42ms UTC 03:38 PVG 11:38 LAX 20:38 JFK 23:38
    Do have faith in what you're doing.
    ubao snddm index pchome yahoo rakuten mypaper meadowduck bidyahoo youbao zxmzxm asda bnvcg cvbfg dfscv mmhjk xxddc yybgb zznbn ccubao uaitu acv GXCV ET GDG YH FG BCVB FJFH CBRE CBC GDG ET54 WRWR RWER WREW WRWER RWER SDG EW SF DSFSF fbbs ubao fhd dfg ewr dg df ewwr ewwr et ruyut utut dfg fgd gdfgt etg dfgt dfgd ert4 gd fgg wr 235 wer3 we vsdf sdf gdf ert xcv sdf rwer hfd dfg cvb rwf afb dfh jgh bmn lgh rty gfds cxv xcv xcs vdas fdf fgd cv sdf tert sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf sdf shasha9178 shasha9178 shasha9178 shasha9178 shasha9178 liflif2 liflif2 liflif2 liflif2 liflif2 liblib3 liblib3 liblib3 liblib3 liblib3 zhazha444 zhazha444 zhazha444 zhazha444 zhazha444 dende5 dende denden denden2 denden21 fenfen9 fenf619 fen619 fenfe9 fe619 sdf sdf sdf sdf sdf zhazh90 zhazh0 zhaa50 zha90 zh590 zho zhoz zhozh zhozho zhozho2 lislis lls95 lili95 lils5 liss9 sdf0ty987 sdft876 sdft9876 sdf09876 sd0t9876 sdf0ty98 sdf0976 sdf0ty986 sdf0ty96 sdf0t76 sdf0876 df0ty98 sf0t876 sd0ty76 sdy76 sdf76 sdf0t76 sdf0ty9 sdf0ty98 sdf0ty987 sdf0ty98 sdf6676 sdf876 sd876 sd876 sdf6 sdf6 sdf9876 sdf0t sdf06 sdf0ty9776 sdf0ty9776 sdf0ty76 sdf8876 sdf0t sd6 sdf06 s688876 sd688 sdf86