La fonction python ne renvoyant que la version du package dans un format lisible par machine:
from importlib.metadata import version
version('numpy')
Avant python 3.8:
pip install importlib-metadata
from importlib_metadata import version
version('numpy')
L'équivalent bash (ici également invoqué depuis python) serait beaucoup plus complexe (mais plus robuste - voir prudence ci-dessous):
import subprocess
def get_installed_ver(pkg_name):
bash_str="pip freeze | grep -w %s= | awk -F '==' {'print $2'} | tr -d '\n'" %(pkg_name)
return(subprocess.check_output(bash_str, shell=True).decode())
Exemple d'utilisation:
# pkg_name="xgboost"
# pkg_name="Flask"
# pkg_name="Flask-Caching"
pkg_name="scikit-learn"
print(get_installed_ver(pkg_name))
>>> 0.22
Notez que dans les deux cas, le pkg_nameparamètre doit contenir le nom du package au format renvoyé par pip freezeet non tel qu'il est utilisé pendant import, par exemple, scikit-learnpas sklearnou Flask-Cachingpas flask_caching.
Notez que bien que l'invocation pip freezedans la version bash puisse sembler inefficace, seule cette méthode s'avère suffisamment robuste pour empaqueter les particularités et les incohérences de nommage (par exemple, les soulignés vs les tirets, les petites vs les grandes majuscules et les abréviations telles que sklearnvs scikit-learn).
Attention: dans les environnements complexes, les deux variantes peuvent renvoyer des numéros de version surprenants, incompatibles avec ce que vous pouvez réellement obtenir pendant import.
Un tel problème se pose lorsqu'il existe d'autres versions du package cachées dans un sous-dossier utilisateur site-packages . Pour illustrer les dangers de l'utilisation, version()voici une situation que j'ai rencontrée:
$ pip freeze | grep lightgbm
lightgbm==2.3.1
and
$ python -c "import lightgbm; print(lightgbm.__version__)"
2.3.1
vs.
$ python -c "from importlib_metadata import version; print(version(\"lightgbm\"))"
2.2.3
until you delete the subfolder with the old version (here 2.2.3) from the user folder (only one would normally be preserved by `pip` - the one installed as last with the `--user` switch):
$ ls /home/jovyan/.local/lib/python3.7/site-packages/lightgbm*
/home/jovyan/.local/lib/python3.7/site-packages/lightgbm-2.2.3.dist-info
/home/jovyan/.local/lib/python3.7/site-packages/lightgbm-2.3.1.dist-info
Un autre problème est d'avoir certains packages installés par conda dans le même environnement. S'ils partagent des dépendances avec vos packages installés par pip et que les versions de ces dépendances diffèrent, vous pouvez obtenir des rétrogradations de vos dépendances installées par pip.
Pour illustrer, la dernière version de numpydisponible dans PyPI le 01-01-2020 était 1.18.0, tandis que dans le même temps la conda-forgechaîne d'Anaconda n'avait que la version 1.17.3 numpycomme dernière. Ainsi, lorsque vous avez installé un basemappackage avec conda (comme deuxième), votre ancien pip installé numpyserait rétrogradé par conda à 1.17.3, et la version 1.18.0 deviendrait indisponible pour la importfonction. Dans ce cas, ce version()serait bien et pip freeze/ ou conda listmal:
$ python -c "from importlib_metadata import version; print(version(\"numpy\"))"
1.17.3
$ python -c "import numpy; print(numpy.__version__)"
1.17.3
$ pip freeze | grep numpy
numpy==1.18.0
$ conda list | grep numpy
numpy 1.18.0 pypi_0 pypi
showcommande dans pip: github.com/pypa/pip/issues/33