计算版本号之间的差异

时间:2015-12-18 09:21:22

标签: python version-numbering

this question的答案帮助我比较了两个版本号字符串,看看哪个版本是“更大”,即更新。

我现在需要做的是计算两个版本号之间的实际差异。主要是看是否已发布新的主要版本,或仅发布次要版本。

"1.3.6" - "1.3.3"应该返回"0.0.3"

"5.2.0" - "4.0.0"应该返回"1.2.0"

我可以编写一个自己计算差异的函数(理论上很容易),但是包含pkg_resources已经考虑过的所有情况都很麻烦,比如版本号之间或之后的字母。

我查看过pkg_resources的纪录片,但简单的减法似乎不起作用。还有其他已经实现的解决方案吗?

编辑:好的,简单的减法没有多大意义,现在我考虑一下。它会稀释主要版本和次要版本之间的边界(例如“2.1” - “1.2”=“0.9”,这根本没有用)。 (谢谢@Jeremy Banks)

4 个答案:

答案 0 :(得分:2)

这是我刚才写的一个函数,它按照这些方式做了一些事情:

def diffver(v1, v2):
    v1s = map(int, v1.split('.'))
    v2s = map(int, v2.split('.'))

    for ii, (v1r, v2r) in enumerate(zip(v1s, v2s), 1):
        if v1r != v2r:
            return ii, v1r - v2r

    return ii, 0

print diffver("4.0.0", "5.2.0")
print diffver("5.1.0", "5.2.0")
print diffver("5.4.0", "5.2.0")
print diffver("5.4.0", "5.4.0")

打印:

(1, -1)
(2, -1)
(2, 2)
(3, 0)

这个想法是返回一个元组(PART,DIFF),其中PART为1表示major,2表示minor,等等,DIFF表示该部分有多么不同。没有区别给你PART是多少部分被比较。

答案 1 :(得分:1)

您可以逐个比较每个部分:

def compare(a, b):
    a_parts = a.split('.')
    b_parts = b.split('.')
    v = ['major', 'minor', 'build']
    for i in range(3):
        diff = int(a_parts[i]) - int(b_parts[i])
        if diff is 0:
            continue
        if diff > 0:
            direction = 'ahead'
        else:
            direction = 'behind'
            diff = -diff

        return 'pkg is %s %s version %s' %  (diff, v[i], direction)
    return 'version are equal'

print compare('3.2.1', '2.0.0') # pkg is 1 major version ahead
print compare('3.2.1', '3.0.0') # pkg is 2 minor version ahead
print compare('3.2.1', '3.2.0') # pkg is 1 build version ahead
print compare('3.2.1', '3.2.1') # version are equal
print compare('3.2.1', '6.2.1') # pkg is 3 major version behind

如果您的版本号不是标准版(例如:1.2b.4321),您可以使用parse_version之类的工具进行预解析。

答案 2 :(得分:0)

好的,感谢您的评论到目前为止,我现在看到将整个版本号进行比较没有意义。

仅比较整个版本号的“片段”,即仅比较第一或第二部分是有意义的。我可能会这样做。

更具体地说: 我将首先看看主要版本是否存在差异(第一部分)。 如果是这种情况,次要版本无关紧要。如果不是这种情况,我会继续比较版本号的下一部分。

这个解决方案仍然会让包含版本号包括字母(例如“1.8.4b”)的案例变得麻烦,但我想没有办法解决它。

答案 3 :(得分:0)

可能更紧凑:

def compare_versions(ver1, ver2):
    numbers1 = [int(x) for x in ver1.split('.')]
    numbers2 = [int(x) for x in ver2.split('.')]
    return '.'.join(str(v1 - v2)  for v1, v2 in zip(numbers1, numbers2))

>>> compare_versions("1.3.6", "1.3.3")
'0.0.3'    
>>> compare_versions("5.2.0", "4.0.0" )
'1.2.0'

缩短一行的变体:

def compare_versions(ver1, ver2):
    split_dot = lambda ver: [int(x) for x in ver.split('.')]
    return  '.'.join(str(v1 - v2)  for v1, v2 in zip(split_dot(ver1), split_dot(ver2)))