使用pip,是否有可能找出当前安装的软件包的哪个版本?

我知道pip安装XYZ -升级,但我想知道是否有类似pip信息XYZ的东西。如果不是什么最好的方式来告诉我目前使用的版本。


当前回答

最简单的方法是:

import jinja2
print jinja2.__version__

其他回答

PIP list也可以被告知将其输出格式化为json。 这可能是一种更安全的解析版本的方法。

pip list --no-index --format=json | \
  jq -r '.[] | select(.name=="Jinja2").version'
# 2.10.1

您可以使用grep命令来查找。

pip show <package_name>|grep Version

例子:

pip show urllib3|grep Version

将只显示版本。

Metadata-Version: 2.0 版本:1.12

python函数只返回机器可读格式的包版本:

from importlib.metadata import version 
version('numpy')

python 3.8之前:

pip install importlib-metadata 
from importlib_metadata import version
version('numpy')

bash的等效程序(这里也是从python调用的)要复杂得多(但更健壮——请参阅下面的警告):

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())

示例用法:

# pkg_name="xgboost"
# pkg_name="Flask"
# pkg_name="Flask-Caching"
pkg_name="scikit-learn"

print(get_installed_ver(pkg_name))
>>> 0.22

请注意,在这两种情况下,pkg_name参数应该包含pip freeze返回的格式的包名,而不是导入过程中使用的格式,例如scikit-learn而不是sklearn或Flask-Caching,而不是flask_caching。

请注意,虽然在bash版本中调用pip freeze可能看起来效率不高,但只有这个方法被证明足够健壮,可以打包命名特性和不一致(例如,下划线与破破号,小写与大写,以及缩写,如sklearn与scikit-learn)。

注意:在复杂环境中,这两个变体都可能返回令人惊讶的版本号,与您在导入过程中实际得到的版本号不一致。

当用户site-packages子文件夹中隐藏了其他版本的包时,就会出现这样的问题。为了说明使用version()的危险,下面是我遇到的一个情况:

$ 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

另一个问题是在相同的环境中安装了一些conda包。如果它们与pip安装的包共享依赖关系,并且这些依赖关系的版本不同,则可能会降级pip安装的依赖关系。

举例来说,在2020年04月01日,PyPI中可用的numpy的最新版本是1.18.0,而与此同时,Anaconda的conda-forge频道的numpy的最新版本只有1.17.3。因此,当您使用conda(作为第二个)安装基图包时,您之前在pip上安装的numpy将被conda降级为1.17.3,并且版本1.18.0将无法用于导入函数。在这种情况下,version()是正确的,pip freeze/conda list是错误的:

$ 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

PIP show在python 3.7中工作:

pip show selenium
Name: selenium
Version: 4.0.0a3
Summary: Python bindings for Selenium
Home-page: https://github.com/SeleniumHQ/selenium/
Author: UNKNOWN
Author-email: UNKNOWN
License: Apache 2.0
Location: c:\python3.7\lib\site-packages\selenium-4.0.0a3-py3.7.egg
Requires: urllib3
Required-by:

还有一个叫做pip-check的工具,它可以让你快速浏览所有安装的包及其更新状态:

我自己没用过;只是偶然发现了这个SO问题,因为它没有被提及……