当前位置: 首页 > 知识库问答 >
问题:

如何比较 Python 中的版本号?

柳宏深
2023-03-14

我正在浏览一个包含鸡蛋的目录,以将这些鸡蛋添加到sys.path。如果目录中有同一个.egg的两个版本,我只想添加最新版本。

我有一个正则表达式r"^(?P

因为我比较的是字符串,所以2排序高于10,但这对于版本来说是不正确的。

>>> "2.3.1" > "10.1.1"
True

我可以执行一些拆分、解析、转换为int等操作,最终我会找到一个解决方法。但这是Python,而不是Java。有一种比较版本字符串的优雅方法吗?


共有3个答案

锺离声
2023-03-14
def versiontuple(v):
    return tuple(map(int, (v.split("."))))

>>> versiontuple("2.3.1") > versiontuple("10.1.1")
False
诸葛茂勋
2023-03-14

打包库包含用于处理版本和其他与打包相关的功能的实用程序。这实现了PEP 0440——版本识别,也能够解析不遵循PEP的版本。pip和其他常见的Python工具使用它来提供版本解析和比较。

$ pip install packaging
from packaging.version import parse as parse_version
version = parse_version('1.0.3.dev')

这是从setuptools和pkg_resources中的原始代码中分离出来的,以提供更轻量级,更快的包。

在打包库存在之前,这个功能是(并且仍然可以)在pkg_resources中找到的,一个由setup工具提供的包。然而,这不再是首选,因为setup工具不再保证被安装(其他打包工具存在),具有讽刺意味的是,pkg_resources在导入时使用了相当多的资源。然而,所有的文档和讨论仍然是相关的。

parse_version() 文档中:

解析由PEP 440定义的项目的版本字符串。返回的值将是一个表示版本的对象。这些对象可以相互比较和排序。排序算法由PEP 440定义,并且添加了任何不是有效PEP 440版本的版本将被视为小于任何有效PEP 440版本,无效版本将继续使用原始算法进行排序。

参考的“原始算法”是在PEP 440存在之前的旧版本文档中定义的。

从语义上讲,该格式是distutils的StrictVersionLooseVersion类之间的粗略交叉;如果您为其提供适用于 StrictVersion 的版本,那么它们将以相同的方式进行比较。否则,比较更像是LooseVersion的“更智能”形式。可以创建病理版本编码方案来欺骗这个解析器,但它们在实践中应该非常罕见。

该文档提供了一些示例:

如果您想确定您选择的编号方案按照您认为的方式工作,您可以使用pkg_resources.parse_version()函数来比较不同的版本号:

>>> from pkg_resources import parse_version
>>> parse_version('1.9.a.dev') == parse_version('1.9a0dev')
True
>>> parse_version('2.1-rc2') < parse_version('2.1')
True
>>> parse_version('0.6a9dev-r41475') < parse_version('0.6a9')
True
祁高格
2023-03-14
匿名用户

使用packaging.version.parse

>>> # pip install packaging
>>> from packaging import version
>>> version.parse("2.3.1") < version.parse("10.1.2")
True
>>> version.parse("1.3.a4") < version.parse("10.1.2")
True
>>> isinstance(version.parse("1.3.a4"), version.Version)
True
>>> isinstance(version.parse("1.3.xy123"), version.LegacyVersion)
True
>>> version.Version("1.3.xy123")
Traceback (most recent call last):
...
packaging.version.InvalidVersion: Invalid version: '1.3.xy123'

<code>packaging.version。parse</code>是第三方实用程序,但由setuptools使用(因此您可能已经安装了它),并且符合当前的PEP 440;它将返回<code>packaging.version。版本(如果版本兼容)和packaging.Version。如果不是,则LegacyVersion。后者将始终在有效版本之前排序。

注意:包装最近被出售到setuptools中。

您可能会遇到一个古老且现已弃用的方法是distutils.version,它没有文档,仅符合已取代的PEP 386;

>>> from distutils.version import LooseVersion, StrictVersion
>>> LooseVersion("2.3.1") < LooseVersion("10.1.2")
True
>>> StrictVersion("2.3.1") < StrictVersion("10.1.2")
True
>>> StrictVersion("1.3.a4")
Traceback (most recent call last):
...
ValueError: invalid version number '1.3.a4'

如您所见,它将有效的PEP 440版本视为“不严格”,因此与现代Python对有效版本的概念不符。

由于< code>distutils.version没有文档记录,这里是相关的文档字符串。

 类似资料:
  • 问题内容: 我正在走一个包含鸡蛋的目录,将这些鸡蛋添加到sys.path。如果目录中有相同.egg的两个版本,我只想添加最新的一个。 我有一个正则表达式·可以从文件名中提取名称和版本。问题是比较版本号,它是一个类似的字符串2.3.1。 由于我在比较字符串,所以2在10之上排序,但这对于版本是不正确的。 我可以进行一些拆分,解析,转换为int等操作,最终得到解决方法。但这是Python,而不是Jav

  • 问题内容: 我想写一个样功能,比较两个版本号,并返回,或根据自己的比较valuses。 如果版本A早于版本B,则返回 返回如果版本A和B是等价的 如果版本A比版本B更新,则返回 每个小节都应解释为一个数字,因此1.10> 1.1。 所需的功能输出为 这是我的实现,有待改进: 我正在使用Python 2.4.5 btw。(安装在我的工作地点…)。 这是您可以使用的小型“测试套件” 问题答案: 删除字

  • 问题内容: 是否有用于比较版本号的标准习语?我不能只使用直接的String compareTo,因为我尚不知道最大的点释放数将是多少。我需要比较版本,并满足以下条件: 问题答案: 用点作为定界符标记字符串,然后从左侧开始并排比较整数转换。

  • 问题内容: 我的表中有固件版本字符串(例如“ 4.2.2”或“ 4.2.16”) 如何比较,选择或排序它们? 我无法使用标准字符串比较:SQL看到的“ 4.2.2”大于“ 4.2.16” 作为版本字符串,我希望4.2.16大于4.2.2 我想考虑一下固件版本中可以包含chars的原因:4.24a1、4.25b3 …为此,通常,具有chars的子字段具有固定的长度。 如何进行 ? 问题答案: 最终,

  • 软件包的版本号是个奇怪的东西。它们看起来像十进制的数字,但它们不是。 例如,一个版本号通常的形式为 2.6.4。如果你需要比较两个版本号, 不能做简单的字符串比较,因为 2.6.4 会比 2.6.12 大;也不能进行数字比较, 因为它们不是有效地数字。 Puppet 的 versioncmp 函数会帮我们解决这个问题。 若你给它传递两个版本号,它会比较它们,并返回一个值,指出谁是更大的: ve

  • 问题内容: 我有两个字符串(它们实际上是版本号,它们可以是任何版本号) 我想比较哪个更大。在golang中如何做? 问题答案: 将“ 1.05.00.0156”转换为“ 0001” +“ 0005” +“ 0000” +“ 0156”,然后转换为int64。 将“ 1.0.221.9289”转换为“ 0001” +“ 0000” +“ 0221” +“ 9289”,然后转换为int64。 比较两个