6

我的一个项目使用shlex.quotepython 3.3以来可用。但这与移至 shlex 后不推荐使用shlex.quote的相同。pipes.quote

现在为了兼容性,我正在使用以下代码:

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)

有没有更好的做法?

4

1 回答 1

13

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

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

if sys.version_info < (3, 3):

……如果 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
于 2014-11-06T23:09:37.833 回答