Python 3向后兼容性(shlex.quote vs pipes.quote)

Vic*_*voy 5 python compatibility shlex

我的一个项目使用shlex.quotepython 3.3以来可用.但这shlex.quotepipes.quote移动到shlex后弃用的相同.

现在为兼容性我使用此代码:

def cmd_quote(string):
    import sys
    if int(sys.version[2]) < 3:
        import pipes
        return pipes.quote(string)
    else:
        import shlex
        return shlex.quote(string)
Run Code Online (Sandbox Code Playgroud)

有没有更好的做法?

aba*_*ert 12

首先,如果你想对版本进行数值比较,请使用version_info,不要尝试解析字符串version.*

这也意味着您可以利用元组比较的方式,并编写如下代码:

if sys.version_info < (3, 3):
Run Code Online (Sandbox Code Playgroud)

...如果Python达到3.10.0或4.0,它就不会破坏.

*除非你需要担心1.5和2.0,在这种情况下,你显然在Usenet和StackOverflow之间有一个时间机器网关,你肯定可以想到更好的用途.


无论如何,最好只测试shlex.quote现有产品.这样,对于读者来说,你正在做的事情是显而易见的:shlex.quote如果可能的话,尽可能地使用,pipes.quote如果不是的话.

你会在整个地方看到这种模式 - 甚至在stdlib中,如果可能的话,代码从C加速器模块导入,但如果没有,则使用回退代码(例如,如果你使用的是PyPy而不是CPython).


另外请注意,pipes.quote在2.7记载.不是3.0-3.2(这似乎是你关心...),或2.6,或任何其他版本.你依赖的是特定实现中恰好存在的东西.(嗯,实际上,在所有这些中,*但是,为什么还要依赖它,如果你不需要?)

*据我所知,目前还没有任何3.2的实现有pipesshlex,但没有pipes.quote.未来可能不会有太多新的3.2实现.


此外,虽然它import在函数中间偶尔会有用,但它有点奇怪.如果你在部署它的机器上安装有问题,你真的希望能够成功导入你的模块,但后来又ImportError调用了一些函数吗?这就是人们一直困惑的事情,并一直向SO寻求帮助.:)(显而易见的是sys.modules,在你不需要的时候做所有这些并将字符串转换为整数等等,但是我怀疑这很重要.)


所以,我认为我写它的方式是:

try:
    from shlex import quote as cmd_quote
except ImportError:
    from pipes import quote as cmd_quote
Run Code Online (Sandbox Code Playgroud)