计算版本号之间的差异

Calculate the Difference between Version Numbers

this question 的答案帮助我比较了两个版本号字符串并查看哪个版本是 "greater",即更新。

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

"1.3.6" - "1.3.3" 应该 return "0.0.3"

"5.2.0" - "4.0.0" 应该 return "1.2.0"

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

我看过 pkg_resources 的纪录片,但简单的减法似乎不起作用。对于这个问题是否还有其他已经实施的解决方案?

编辑:好吧,简单的减法没有多大意义,现在我想起来了。它会淡化主要版本和次要版本之间的界限(例如“2.1”-“1.2”=“0.9”,这根本没有帮助)。 (感谢@Jeremy Banks)

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

只有比较整个版本号的"fragments"才有意义,即只比较第一部分或第二部分。这就是我可能会做的。

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

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

您可以逐个比较:

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.

等工具进行预解析

这是我刚刚编写的一个函数,它执行以下操作:

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)

想法是 return 一个元组 (PART, DIFF),其中 PART 为 1 表示主要,2 表示次要,等等,DIFF 表示该部分的差异程度。没有区别给你 PART 是比较了多少部分。

也许更紧凑一点:

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)))