【问题标题】:Find which version of package is installed with pip使用 pip 查找安装了哪个版本的包
【发布时间】:2012-04-30 04:27:06
【问题描述】:

使用 pip 是否可以确定当前安装了哪个版本的包?

我知道pip install XYZ --upgrade,但我想知道是否有类似pip info XYZ 的东西。如果不是,那么告诉我当前使用的版本的最佳方法是什么。

【问题讨论】:

    标签: python pip


    【解决方案1】:

    截至pip 1.3,有一个pip show 命令。

    $ pip show Jinja2
    ---
    Name: Jinja2
    Version: 2.7.3
    Location: /path/to/virtualenv/lib/python2.7/site-packages
    Requires: markupsafe
    

    在旧版本中,pip freezegrep 应该可以很好地完成这项工作。

    $ pip freeze | grep Jinja2
    Jinja2==2.7.3
    

    【讨论】:

    • @techtonik: freezing current modules 到 requirements.txt。
    • @Hugo:我会使用 save 名称。
    • “freeze”的命名是历史性的——它可以追溯到at least 2008。当时,很多人已经熟悉“冷冻”红宝石,所以 pip 借用了当时广泛使用的名称。
    • 这并不明显,也没有记录,但您可以输入 pip show pip 来获取 pip 的版本信息,而不是像我预期的那样输入 pip --version
    • pip freeze 的优点是它可以正确显示可编辑的 VCS 检出版本,而 pip show 则不能。
    【解决方案2】:

    您还可以安装yolk,然后运行yolk -l,这也会提供一些不错的输出。这是我为我的小 virtualenv 得到的:

    (venv)CWD> /space/vhosts/pyramid.xcode.com/venv/build/unittest 
    project@pyramid 43> yolk -l
    Chameleon       - 2.8.2        - active 
    Jinja2          - 2.6          - active 
    Mako            - 0.7.0        - active 
    MarkupSafe      - 0.15         - active 
    PasteDeploy     - 1.5.0        - active 
    Pygments        - 1.5          - active 
    Python          - 2.7.3        - active development (/usr/lib/python2.7/lib-dynload)
    SQLAlchemy      - 0.7.6        - active 
    WebOb           - 1.2b3        - active 
    account         - 0.0          - active development (/space/vhosts/pyramid.xcode.com/project/account)
    distribute      - 0.6.19       - active 
    egenix-mx-base  - 3.2.3        - active 
    ipython         - 0.12         - active 
    logilab-astng   - 0.23.1       - active 
    logilab-common  - 0.57.1       - active 
    nose            - 1.1.2        - active 
    pbkdf2          - 1.3          - active 
    pip             - 1.0.2        - active 
    pyScss          - 1.1.3        - active 
    pycrypto        - 2.5          - active 
    pylint          - 0.25.1       - active 
    pyramid-debugtoolbar - 1.0.1        - active 
    pyramid-tm      - 0.4          - active 
    pyramid         - 1.3          - active 
    repoze.lru      - 0.5          - active 
    simplejson      - 2.5.0        - active 
    transaction     - 1.2.0        - active 
    translationstring - 1.1          - active 
    venusian        - 1.0a3        - active 
    waitress        - 0.8.1        - active 
    wsgiref         - 0.1.2        - active development (/usr/lib/python2.7)
    yolk            - 0.4.3        - active 
    zope.deprecation - 3.5.1        - active 
    zope.interface  - 3.8.0        - active 
    zope.sqlalchemy - 0.7          - active 
    

    【讨论】:

      【解决方案3】:

      我刚刚在 pip 中发送了一个带有增强功能的拉取请求,Hugo Tavares 说:

      (以光谱云为例)

      $ pip show specloud
      
      Package: specloud
      Version: 0.4.4
      Requires:
      nose
      figleaf
      pinocchio
      

      【讨论】:

      【解决方案4】:

      Pip 1.3 现在也有一个list 命令:

      $ pip list
      argparse (1.2.1)
      pip (1.5.1)
      setuptools (2.1)
      wsgiref (0.1.2)
      

      【讨论】:

      • 说包名是 X。要查找版本 - 使用 pip list 和 import X 然后 X.__version__ 有什么区别?两个都是包版本吗?
      • 两者都有效,但pip list 是通用的,__version__ 不是。我还看到version()get_version() 用于导入的。
      【解决方案5】:

      加上 --outdated 作为额外参数,您将获得您正在使用的软件包的当前和最新版本:

      $ pip list --outdated
      distribute (Current: 0.6.34 Latest: 0.7.3)
      django-bootstrap3 (Current: 1.1.0 Latest: 4.3.0)
      Django (Current: 1.5.4 Latest: 1.6.4)
      Jinja2 (Current: 2.6 Latest: 2.8)
      

      所以结合 AdamKG 的回答:

      $ pip list --outdated | grep Jinja2
      Jinja2 (Current: 2.6 Latest: 2.8)
      

      也检查 pip-toolshttps://github.com/nvie/pip-tools

      【讨论】:

      • 一个有趣的选项。不过,我宁愿把它们都列出来,如果它们中的任何一个已经过时了,请告诉我。
      • 你也可以使用-o
      【解决方案6】:

      最简单的方法是这样的:

      import jinja2
      print jinja2.__version__
      

      【讨论】:

      • 这仅适用于在其源代码中定义了__version__ 的包。许多软件包没有。
      • 在打包时包含此版本是一种好习惯,还是只在 setup.py 文件版本参数中包含该版本是一种好习惯?
      • 这种方法对于import的预期输入和pip freeze的输出之间的包命名不一致(至少有3种类型)也不健壮。
      【解决方案7】:

      您可以使用 grep 命令查找。

      pip show <package_name>|grep Version
      

      例子:

      pip show urllib3|grep Version
      

      将仅显示版本。

      元数据版本:2.0
      版本:1.12

      【讨论】:

      【解决方案8】:

      在windows上,你可以发出如下命令:

      pip show setuptools | findstr "Version"
      

      输出:

      Version: 34.1.1
      

      【讨论】:

        【解决方案9】:

        对于 Windows,您可以

        1. 打开 cmd 并输入 python,按回车。

        2. 输入导入并按回车。

        3. 键入 ._version__ 并按 Enter。

        正如您在此处的屏幕截图中看到的那样,我正在使用这种方法来检查串行模块的版本。


        【讨论】:

          【解决方案10】:

          There's also a tool 称为pip-check,它可以让您快速了解所有已安装的软件包及其更新状态:

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

          【讨论】:

          • 如何在windows上运行
          • @vela 我希望它在 Windows 上的工作方式完全相同。当然,您必须先install it,就像在任何系统上一样。
          【解决方案11】:

          在问题中,没有提到哪个操作系统用户正在使用(Windows/Linux/Mac)

          因为有几个答案可以在 Mac 和 Linux 上完美运行。

          如果用户试图在 Windows 上查找 python 包的版本,可以使用以下命令。

          在 PowerShell 中使用以下命令:

          pip list | findstr &lt;PackageName&gt;

          例子:-pip list | findstr requests

          输出:requests 2.18.4

          【讨论】:

            【解决方案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 返回的格式的包名称,而不是import 期间使用的格式,例如scikit-learn 不是 sklearnFlask-Caching,不是 flask_caching

            请注意,虽然在 bash 版本中调用 pip freeze 可能看起来效率低下,但只有这种方法被证明对于包命名特性和不一致(例如下划线与破折号、小写与大写以及诸如 sklearnscikit-learn)。

            注意:在复杂的环境中,这两种变体都可能返回令人惊讶的版本号,这与您在import 期间实际获得的内容不一致。

            user 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 年 4 月 1 日 PyPI 中可用的 numpy 的最新版本是 1.18.0,而同时 Anaconda 的 conda-forge 频道在 numpy 上只有 1.17.3 版本作为他们的最新版本.因此,当您使用 conda(作为第二个)安装 basemap 软件包时,您之前 pip 安装的 numpy 将被 conda 降级到 1.17.3,并且版本 1.18.0 将无法用于 import 功能。在这种情况下,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
            

            【讨论】:

            • 为什么不使用importlib.metadata.version('NameOfProject')docs.python.org/3/library/…
            • 很棒的发现@sinoroc!我认为您应该将其发布为答案,我将删除我设计过度的问题:) 示例 PoC:from importlib_metadata import version; version('Flask-Caching')
            • 我让你去吧
            • 您的最新编辑让我感到惊讶。你能试试python -c "import pkg_resources; print(pkg_resources.get_distribution('lightgbm').version)"吗?
            • 那个给你正确的答案 - 安装的最新版本(2.3.1),而version() 仍然返回最早(最旧)的版本(2.2.3)。您可以通过使用--user 开关安装两个版本来复制此结果,但手动保留lightgbm-2.2.3.dist-info 文件夹,以将它们放在一起,如上所述(pip 通常将其删除 - 直到它没有)。
            【解决方案13】:

            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:
            

            【讨论】:

            • 这不是标准答案。
            【解决方案14】:

            使用 Python 代码执行此操作:

            使用importlib.metadata.version

            Python ≥3.8

            import importlib.metadata
            importlib.metadata.version('beautifulsoup4')
            '4.9.1'
            

            Python ≤3.7

            (使用importlib_metadata.version

            !pip install importlib-metadata
            
            import importlib_metadata
            importlib_metadata.version('beautifulsoup4')
            '4.9.1'
            

            使用pkg_resources.Distribution

            import pkg_resources
            pkg_resources.get_distribution('beautifulsoup4').version
            '4.9.1'
            pkg_resources.get_distribution('beautifulsoup4').parsed_version
            <Version('4.9.1')>
            

            sinorocmirekphd 归功于 cmets。

            【讨论】:

              【解决方案15】:
              import pkg_resources
              packages = [dist.project_name for dist in pkg_resources.working_set]
              try:
                 for count, item in enumerate(packages):
                    print(item, pkg_resources.get_distribution(item).version)
              except:
                  pass here
              

              压痕可能并不完美。我使用 Try- except 块的原因是很少有库名称会因为解析库名称来处理版本而引发错误。即使 packages 变量将包含您环境中安装的所有库。

              【讨论】:

                【解决方案16】:

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

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

                【讨论】:

                • 我第一次听说 JSON 输出。谢谢,@Romain!
                猜你喜欢
                • 2011-09-28
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多