2

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

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

"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

4 回答 4

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 表示主要,2 表示次要等,而 DIFF 表示该部分的不同之处。没有区别让您 PART 是比较了多少部分。

于 2015-12-18T09:43:48.800 回答
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.

于 2015-12-18T09:39:31.990 回答
0

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

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

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

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

于 2015-12-18T09:36:54.077 回答
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)))
于 2015-12-18T09:58:28.210 回答