Python将版本号与动态比较说明符

时间:2016-04-25 22:04:25

标签: python

给出两个版本号和一个比较说明符:

def check_versions(ver1, specifier, ver2):
    # TODO

check_versions("1.2.3", ">=", "2.0.0") # Should return True
check_versions("1.2.3", "==", "2.0.0") # Should return False

我想将比较应用于两个版本,以便从上面获得预期的输出。

我发现我可以使用LooseVersion中的distutils.version来比较版本,如下所示:

LooseVersion("1.2.3") >= LooseVersion("2.0.0")

但是如何让比较本身取决于传入的specifier

我可以使用here中的解决方案:

def check_versions(ver1, specifier, ver2):
    return {
        '==': LooseVersion(ver1) == LooseVersion(ver2),
        '>=': LooseVersion(ver1) >= LooseVersion(ver2),
        '<=': LooseVersion(ver1) <= LooseVersion(ver2),
        '>': LooseVersion(ver1) > LooseVersion(ver2),
        '<': LooseVersion(ver1) < LooseVersion(ver2),
    }.get(x, False)

但这对我来说真的很笨拙。有没有更优雅的解决方案?

2 个答案:

答案 0 :(得分:6)

您可以为已使用的运算符创建查找,而不是创建包含所有可能的版本比较的字典,例如:

import operator as op
from distutils.version import LooseVersion

lookup = {'<': op.lt, '<=': op.le, '==': op.eq, '>=': op.ge, '>': op.gt}

def check_versions(ver1, specifier, ver2):
    try:
        return lookup[specifier](LooseVersion(ver1), LooseVersion(ver2))
    except KeyError:
        # unknown specifier
        return False

答案 1 :(得分:1)

您可以使用eval

def check_versions(ver1, specifier, ver2):
    return eval("LooseVersion(ver1) " + specifier + " LooseVersion(ver2)")

但请注意,如果specifier来自用户输入,则可能会收到恶意电话:

check_versions("1.0.0", " == 1; pkg_resources.get_distribution("really bad virus");
                 import really_bad_virus; really_bad_virus.bobby_tables();", "1.0.0")

如果是这样,你可以在评估之前sanitize your inputs

def check_versions(ver1, specifier, ver2):
    if specifier in ['==', '<=', '>=', '>', '>']:
        return eval("LooseVersion(ver1) " + specifier + " LooseVersion(ver2)")