Ich gehe durch ein Verzeichnis, das Eier enthält, um diese Eier dem hinzuzufügen sys.path
. Wenn das Verzeichnis zwei Versionen derselben .egg-Datei enthält, möchte ich nur die neueste hinzufügen.
Ich habe einen regulären Ausdruck r"^(?P<eggName>\w+)-(?P<eggVersion>[\d\.]+)-.+\.egg$
, um den Namen und die Version aus dem Dateinamen zu extrahieren. Das Problem besteht darin, die Versionsnummer zu vergleichen, bei der es sich um eine Zeichenfolge handelt 2.3.1
.
Da ich Zeichenfolgen vergleiche, 2 Sortierungen über 10, aber das ist für Versionen nicht korrekt.
>>> "2.3.1" > "10.1.1"
True
Ich könnte etwas aufteilen, analysieren, in int umwandeln usw., und ich würde irgendwann eine Problemumgehung bekommen. Aber das ist Python, nicht Java . Gibt es eine elegante Möglichkeit, Versionszeichenfolgen zu vergleichen?
quelle
distutils.version
es keine Papiere gibt.version.py
Quellcode. Sehr schön ausgedrückt!packaging.version.parse
kann nicht vertraut werden, um Versionen zu vergleichen. Versuchen Sie esparse('1.0.1-beta.1') > parse('1.0.0')
zum Beispiel.Die Verpackungsbibliothek enthält Dienstprogramme zum Arbeiten mit Versionen und anderen verpackungsbezogenen Funktionen. Dies implementiert PEP 0440 - Versionsidentifikation und kann auch Versionen analysieren, die nicht dem PEP folgen. Es wird von pip und anderen gängigen Python-Tools verwendet, um das Parsen und Vergleichen von Versionen zu ermöglichen.
Dies wurde vom ursprünglichen Code in setuptools und pkg_resources abgespalten, um ein leichteres und schnelleres Paket bereitzustellen.
Bevor die Verpackungsbibliothek existierte, wurde (und kann) diese Funktionalität in pkg_resources gefunden, einem Paket, das von setuptools bereitgestellt wird. Dies wird jedoch nicht mehr bevorzugt, da die Installation von Setuptools nicht mehr garantiert ist (andere Verpackungswerkzeuge sind vorhanden) und pkg_resources beim Import ironischerweise eine Menge Ressourcen verwendet. Alle Dokumente und Diskussionen sind jedoch weiterhin relevant.
Aus den
parse_version()
Dokumenten :Der "ursprüngliche Algorithmus", auf den verwiesen wird, wurde in älteren Versionen der Dokumente definiert, bevor PEP 440 existierte.
Die Dokumentation enthält einige Beispiele:
quelle
quelle
map()
Funktion vollständig, wie das Ergebnissplit()
ist bereits Saiten. Aber das wollen Sie sowieso nicht, denn der ganze Grund, sie zu ändern,int
ist, dass sie richtig als Zahlen verglichen werden. Ansonsten"10" < "2"
.versiontuple("1.0") > versiontuple("1")
. Die Versionen sind die gleichen, aber die Tupel erstellt(1,)!=(1,0)
distutils.version.LooseVersion
. Dafür ist es da.Was ist falsch daran, die Versionszeichenfolge in ein Tupel umzuwandeln und von dort fortzufahren? Scheint mir elegant genug
Die Lösung von @ kindall ist ein schnelles Beispiel dafür, wie gut der Code aussehen würde.
quelle
setuptools
wirdpkg_resources
.pkg_resources
und dass Annahmen einer einfachen Paketbenennung möglicherweise nicht immer ideal sind.sys.version_info > (3, 6)
oder was auch immer.Es ist ein Verpackungspaket verfügbar, mit dem Sie Versionen gemäß PEP-440 sowie ältere Versionen vergleichen können.
Unterstützung für ältere Versionen:
Vergleich der Legacy-Version mit der PEP-440-Version.
quelle
packaging.version.Version
und wundernpackaging.version.parse
: "[version.parse
] nimmt eine Versionszeichenfolge und analysiert sie als,Version
wenn die Version eine gültige PEP 440-Version ist, andernfalls wird sie als analysiertLegacyVersion
." (wohingegenversion.Version
erhöhen würdeInvalidVersion
; Quelle )Mit dem Semver- Paket können Sie feststellen, ob eine Version eine semantische Versionsanforderung erfüllt. Dies ist nicht dasselbe wie der Vergleich zweier tatsächlicher Versionen, sondern eine Art Vergleich.
Beispielsweise sollte Version 3.6.0 + 1234 mit Version 3.6.0 identisch sein.
quelle
Veröffentlichung meiner vollen Funktion basierend auf Kindalls Lösung. Ich konnte alle alphanumerischen Zeichen unterstützen, die mit den Zahlen gemischt waren, indem ich jeden Versionsabschnitt mit führenden Nullen auffüllte.
Obwohl es sicherlich nicht so hübsch ist wie seine Einzeiler-Funktion, scheint es mit alphanumerischen Versionsnummern gut zu funktionieren. (Stellen
zfill(#)
Sie den Wert nur entsprechend ein, wenn Ihr Versionsverwaltungssystem lange Zeichenfolgen enthält.).
quelle
So wie
setuptools
es geht, nutzt es diepkg_resources.parse_version
Funktion. Es sollte PEP440 sein konform sein.Beispiel:
quelle
pkg_resources
ist ein Teil vonsetuptools
, was davon abhängtpackaging
. Sehen Sie sich andere Antworten anpackaging.version.parse
, die eine identische Implementierung habenpkg_resources.parse_version
.Ich suchte nach einer Lösung, die keine neuen Abhängigkeiten hinzufügt. Schauen Sie sich die folgende (Python 3) Lösung an:
BEARBEITEN: Variante mit Tupelvergleich hinzugefügt. Natürlich ist die Variante mit Tupelvergleich schöner, aber ich habe nach der Variante mit ganzzahligem Vergleich gesucht
quelle