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

我有一个正则表达式r"^(?P<eggName>\w+)-(?P<eggVersion>[\d\.]+)-.+\.egg$来从文件名中提取名称和版本.问题是比较版本号,它是一个类似2.3.1的字符串.

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

>>> "2.3.1" > "10.1.1"
True

我可以做一些拆分、解析、转换为int等等,最终我会找到一个解决方法.但这是Python,not Java.有没有比较版本字符串的优雅方法?

推荐答案

使用packaging.version.parse.

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

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

Note:包装最近达到了vendored into setuptools种.


你可能会遇到的一个古老的now deprecated种方法是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'

正如您所见,它将有效的PEP440版本视为"不严格",因此与现代Python的有效版本概念不符.

由于distutils.version是未记录的,所以here是相关的文档字符串.

Python相关问答推荐

调查TensorFlow和PyTorch性能的差异

带有Postgres的Flask-Data在调用少量API后崩溃

为什么我的代码会进入无限循环?

如何将不同长度的新列添加到现有的框架中

使用Python和PRNG(不是梅森龙卷风)有效地生成伪随机浮点数在[0,1)中均匀?

在Arrow上迭代的快速方法.Julia中包含3000万行和25列的表

更改Seaborn条形图中的x轴日期时间限制

覆盖Django rest响应,仅返回PK

使用GEKKO在简单DTE系统中进行一致初始化

计算所有前面行(当前行)中列的值

如何使用Google Gemini API为单个提示生成多个响应?

点到面的Y距离

连接两个具有不同标题的收件箱

使可滚动框架在tkinter环境中看起来自然

无法通过python-jira访问jira工作日志(log)中的 comments

图像 pyramid .难以创建所需的合成图像

所有列的滚动标准差,忽略NaN

形状弃用警告与组合多边形和多边形如何解决

matplotlib图中的复杂箭头形状

剪切间隔以添加特定日期