Gunakan 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
adalah utilitas pihak ketiga tetapi digunakan oleh setuptools (jadi Anda mungkin sudah menginstalnya) dan sesuai dengan PEP 440 saat ini ; itu akan mengembalikan packaging.version.Version
jika versi tersebut sesuai dan packaging.version.LegacyVersion
jika tidak. Yang terakhir akan selalu mengurutkan sebelum versi yang valid.
Catatan : kemasan baru-baru ini dibatalkan ke dalam setuptools .
Alternatif kuno yang masih digunakan oleh banyak perangkat lunak adalah distutils.version
, dibangun tetapi tidak berdokumen dan hanya sesuai dengan PEP 386 yang digantikan ;
>>> 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'
Seperti yang Anda lihat itu melihat versi PEP 440 yang valid sebagai "tidak ketat" dan karenanya tidak cocok dengan gagasan Python modern tentang apa versi yang valid.
Seperti distutils.version
tidak berdokumen, inilah dokumen yang relevan.
distutils.version
tidak berdokumen.version.py
kode sumber. Sangat bagus!packaging.version.parse
tidak bisa dipercaya untuk membandingkan versi. Cobaparse('1.0.1-beta.1') > parse('1.0.0')
misalnya.The kemasan perpustakaan berisi utilitas untuk bekerja dengan versi dan fungsi-terkait kemasan lainnya. Ini mengimplementasikan PEP 0440 - Identifikasi Versi dan juga dapat mengurai versi yang tidak mengikuti PEP. Ini digunakan oleh pip, dan alat Python umum lainnya untuk menyediakan parsing dan perbandingan versi.
Ini dipisahkan dari kode asli di setuptools dan pkg_resources untuk menyediakan paket yang lebih ringan dan lebih cepat.
Sebelum pustaka pengemasan ada, fungsi ini (dan masih dapat) ditemukan di pkg_resources, paket yang disediakan oleh setuptools. Namun, ini tidak lagi disukai karena setuptools tidak lagi dijamin untuk diinstal (alat kemasan lain ada), dan pkg_resources ironisnya menggunakan sumber daya yang cukup banyak ketika diimpor. Namun, semua dokumen dan diskusi masih relevan.
Dari
parse_version()
dokumen :"Algoritma asli" yang dirujuk didefinisikan dalam versi dokumen yang lebih lama, sebelum PEP 440 ada.
The dokumentasi memberikan beberapa contoh:
sumber
sumber
map()
fungsi sepenuhnya, karena hasilnya sudahsplit()
berupa string. Tetapi Anda tidak ingin melakukan itu, karena seluruh alasan untuk mengubahnya adalah agar mereka membandingkannya dengan benar sebagai angka. Jika tidak .int
"10" < "2"
versiontuple("1.0") > versiontuple("1")
. Versi-versinya sama, tetapi tupel dibuat(1,)!=(1,0)
distutils.version.LooseVersion
. Untuk itulah ia ada.Apa yang salah dengan mengubah string versi menjadi tuple dan beralih dari sana? Tampak cukup elegan untukku
Solusi @ kindall adalah contoh cepat tentang seberapa baik kode akan terlihat.
sumber
setuptools
, yaitupkg_resources
.pkg_resources
, dan bahwa asumsi penamaan paket sederhana mungkin tidak selalu ideal.sys.version_info > (3, 6)
atau apa pun.Ada paket kemasan yang tersedia, yang akan memungkinkan Anda untuk membandingkan versi sesuai PEP-440 , serta versi lama.
Dukungan versi lama:
Membandingkan versi lawas dengan versi PEP-440.
sumber
packaging.version.Version
danpackaging.version.parse
: "[version.parse
] mengambil string versi dan akan menguraikannya sebagaiVersion
jika versi tersebut adalah versi PEP 440 yang valid, jika tidak maka akan menguraikannya sebagaiLegacyVersion
." (padahalversion.Version
akan memunculkanInvalidVersion
; sumber )Anda dapat menggunakan paket semver untuk menentukan apakah suatu versi memenuhi persyaratan versi semantik . Ini tidak sama dengan membandingkan dua versi aktual, tetapi merupakan jenis perbandingan.
Misalnya, versi 3.6.0 + 1234 harus sama dengan 3.6.0.
sumber
Memposting fungsi lengkap saya berdasarkan solusi Kindall. Saya dapat mendukung setiap karakter alfanumerik yang dicampur dengan angka-angka dengan mengisi setiap bagian versi dengan angka nol di depan.
Meskipun tentu saja tidak secantik fungsi one-liner-nya, tampaknya berfungsi dengan baik dengan nomor versi alpha-numeric. (Pastikan untuk menetapkan
zfill(#)
nilai dengan tepat jika Anda memiliki string panjang di sistem versi Anda.).
sumber
Cara
setuptools
melakukannya, ia menggunakanpkg_resources.parse_version
fungsi. Itu harus PEP440 sesuai dengan .Contoh:
sumber
pkg_resources
adalah bagian darisetuptools
, yang tergantung padapackaging
. Lihat jawaban lain yang membahaspackaging.version.parse
, yang memiliki implementasi yang identik denganpkg_resources.parse_version
.Saya sedang mencari solusi yang tidak akan menambah dependensi baru. Lihat solusi (Python 3) berikut:
EDIT: menambahkan varian dengan perbandingan tuple. Tentu saja varian dengan perbandingan tuple lebih bagus, tetapi saya mencari varian dengan perbandingan integer
sumber