Viele Python Module von Drittanbietern haben ein Attribut, das die Versionsinformationen für das Modul enthält (normalerweise so etwas wie module.VERSION
oder module.__version__
), manche jedoch nicht.
Besondere Beispiele für solche Module sind libxslt und libxml2.
Ich muss überprüfen, ob zur Laufzeit die richtige Version dieser Module verwendet wird. Gibt es eine Möglichkeit, dies zu tun?
Eine mögliche Lösung wäre, den Quellcode zur Laufzeit einzulesen, zu haschen und ihn dann mit dem Hash der bekannten Version zu vergleichen, aber das ist böse.
Gibt es bessere Lösungen?
Ich würde mich vom Hashing fernhalten. Die verwendete Version von libxslt enthält möglicherweise einen Patch, der sich nicht auf Ihre Verwendung auswirkt.
Als Alternative möchte ich vorschlagen, dass Sie nicht zur Laufzeit prüfen (Sie wissen nicht, ob dies eine schwierige Anforderung ist oder nicht). Für die python Zeug, das ich schreibe und das externe Abhängigkeiten hat (Bibliotheken von Drittanbietern), schreibe ich ein Skript, das Benutzer ausführen können, um ihre python zu überprüfen, ob Die entsprechenden Versionen der Module sind installiert.
Bei Modulen ohne definiertes 'version'-Attribut können Sie die enthaltenen Schnittstellen (Klassen und Methoden) überprüfen, um festzustellen, ob sie mit der erwarteten Schnittstelle übereinstimmen. Nehmen Sie dann in dem Code an, an dem Sie gerade arbeiten, an, dass die Module von Drittanbietern die Schnittstelle haben, die Sie erwarten.
Verwenden Sie pkg_resources . Alles, was von PyPI installiert wurde, sollte mindestens eine Versionsnummer haben.
>>> import pkg_resources
>>> pkg_resources.get_distribution("blogofile").version
'0.7.1'
Einige Ideen:
Sie können verwenden
pip freeze
um die installierten Pakete im Anforderungsformat zu sehen.
Sie können importlib_metadata
Bibliothek dafür.
Wenn Sie python <3.8
, installiere es zuerst mit:
pip install importlib_metadata
Seit python 3.8
es ist in der Standardbibliothek von Python enthalten.
Um die Version eines Pakets zu überprüfen (in diesem Beispiel lxml
), führen Sie Folgendes aus:
>>> from importlib_metadata import version
>>> version('lxml')
'4.3.1'
Beachten Sie, dass dies nur für Pakete funktioniert, die von PyPI installiert wurden. Außerdem müssen Sie einen Paketnamen als Argument an die version
-Methode übergeben, anstatt einen Modulnamen, den dieses Paket bereitstellt (obwohl diese normalerweise identisch sind).
Ich fand es ziemlich unzuverlässig, die verschiedenen verfügbaren Tools zu verwenden (einschließlich des besten pkg_resources
, Das von diese andere Antwort erwähnt wird), da die meisten von ihnen nicht alle Fälle abdecken. Beispielsweise
Da wir einen zuverlässigen Weg brauchten, um die Version von jedem Paket, Modul oder Submodul zu erhalten, schrieb ich getversion . Es ist ganz einfach zu bedienen:
from getversion import get_module_version
import foo
version, details = get_module_version(foo)
Einzelheiten finden Sie in der Dokumentation .