我正在浏览一个包含卵的目录,以便将这些卵添加到sys.path。如果目录中有相同的.egg的两个版本,我只想添加最新的版本。
我有一个正则表达式r ^ (? P < eggName > \ w +) - (? P < eggVersion > (\ d \.]+)-.+\.Egg $从文件名中提取名称和版本。问题是比较版本号,它是一个像2.3.1这样的字符串。
因为我比较字符串,2排序超过10,但这是不正确的版本。
>>> "2.3.1" > "10.1.1"
True
我可以做一些拆分、解析、转换为int等,最终我将得到一个变通方法。但这是Python,不是Java。是否有一种优雅的方法来比较版本字符串?
基于Kindall的解决方案发布我的完整功能。通过用前导零填充每个版本部分,我能够支持混合在数字中的任何字母数字字符。
虽然肯定不如他的一行函数漂亮,但它似乎可以很好地处理字母数字版本号。(如果您的版本控制系统中有较长的字符串,请确保适当地设置zfill(#)值。)
def versiontuple(v):
filled = []
for point in v.split("."):
filled.append(point.zfill(8))
return tuple(filled)
.
>>> versiontuple("10a.4.5.23-alpha") > versiontuple("2a.4.5.23-alpha")
True
>>> "10a.4.5.23-alpha" > "2a.4.5.23-alpha"
False
有包装包可用,这将允许您比较版本按照PEP-440,以及遗留版本。
>>> from packaging.version import Version, LegacyVersion
>>> Version('1.1') < Version('1.2')
True
>>> Version('1.2.dev4+deadbeef') < Version('1.2')
True
>>> Version('1.2.8.5') <= Version('1.2')
False
>>> Version('1.2.8.5') <= Version('1.2.8.6')
True
旧版本支持:
>>> LegacyVersion('1.2.8.5-5-gdeadbeef')
<LegacyVersion('1.2.8.5-5-gdeadbeef')>
比较遗留版本和PEP-440版本。
>>> LegacyVersion('1.2.8.5-5-gdeadbeef') < Version('1.2.8.6')
True
使用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'
package .version.parse是一个第三方实用程序,但被setuptools使用(所以你可能已经安装了它),并且符合当前的PEP 440;如果版本兼容,它将返回package .version. version,如果不兼容,则返回package .version. legacyversion。后者总是在有效版本之前排序。
注意:setuptools最近提供了打包。
您可能遇到的一种古老且现在已弃用的方法是distutils。版本,它是无文档的,只符合取代的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对有效版本的定义。
distutils。版本没有文档,这里是相关的文档字符串。