【问题标题】:How to check version of python modules?如何检查python模块的版本?
【发布时间】:2013-12-09 10:32:57
【问题描述】:

我刚刚安装了 python 模块:constructstatlibsetuptools,如下所示:

# Install setuptools to be able to download the following
sudo apt-get install python-setuptools

# Install statlib for lightweight statistical tools
sudo easy_install statlib

# Install construct for packing/unpacking binary data
sudo easy_install construct

我希望能够(以编程方式)检查他们的版本。是否有与python --version 等效的我可以从命令行运行?

我的python版本是2.7.3

【问题讨论】:

标签: python


【解决方案1】:

我建议使用pip in place of easy_install。使用 pip,您可以使用

列出所有已安装的软件包及其版本
pip freeze

在大多数 linux 系统中,您可以将其通过管道传递给 grep(或在 Windows 上为 findstr)以查找您感兴趣的特定包的行:

Linux:
$ pip freeze | grep lxml
lxml==2.3

Windows:
c:\> pip freeze | findstr lxml
lxml==2.3

对于单个模块,您可以尝试__version__ attribute,但是有些模块没有它:

$ python -c "import requests; print(requests.__version__)"
2.14.2
$ python -c "import lxml; print(lxml.__version__)"
Traceback (most recent call last):
  File "<string>", line 1, in <module>
AttributeError: 'module' object has no attribute '__version__'

最后,由于您问题中的命令以 sudo 为前缀,因此您似乎正在安装到全局 python 环境。强烈建议查看 python virtual environment manager,例如 virtualenvwrapper

【讨论】:

  • 下面建议的答案pip show lxml | grep Version ;这将运行得更快,因为它只检查一个包。
  • 为了完整性:第三个版本是pip list | grep lxml
  • 在Windows系统上怎么样? Windows 中的grep 是什么?由于点冻结| grep lxml 在windwos 上不起作用。
  • @RavenCheuk 使用 pip list | findstr lxml
  • 带有 find 的 windows 变体(短 1 个字符...):pip list |找到“lxml”
【解决方案2】:

你可以试试

>>> import statlib
>>> print statlib.__version__

>>> import construct
>>> print contruct.__version__

更新:这是 PEP 396 推荐的方法。但 PEP 从未被接受并被推迟。事实上,Python 核心开发人员似乎越来越支持推荐 not 包括 __version__ 属性,例如在https://gitlab.com/python-devs/importlib_metadata/-/merge_requests/125

【讨论】:

  • 一些常见库的某些版本(例如inspect)没有__version__ 属性,很遗憾。
  • PySerial 有serial.VERSION。也许还有其他一些常用的模块,它们不遵循 PEP 0396:python.org/dev/peps/pep-0396
  • 很多模块没有版本
  • @sdaffa23fdsf 哪些模块没有版本?不仅仅是串行、检查、PyQt 和 SQLite?见pycmake
  • print(contruct.__version__) 如果使用 Python 3.*
【解决方案3】:

Python >= 3.8:

如果您使用的是 python &gt;=3.8,则可以使用内置库中的模块。要检查包的版本(在此示例中为 construct),请运行:

>>> from importlib.metadata import version
>>> version('construct')
'4.3.1'

Python

使用与setuptools 库一起分发的pkg_resources 模块。请注意,您传递给 get_distribution 方法的字符串应该对应于 PyPI 条目。

>>> import pkg_resources
>>> pkg_resources.get_distribution('construct').version
'2.5.2'

旁注:

  1. 请注意,您传递给get_distribution 方法的字符串应该是包在 PyPI 中注册的名称,而不是您尝试导入的模块名称。不幸的是,这些并不总是相同的(例如,您使用pip install memcached,但使用import memcache)。

  2. 如果您想从命令行应用此解决方案,您可以执行以下操作:

python -c \
  "import pkg_resources; print(pkg_resources.get_distribution('construct').version)"

【讨论】:

  • 即使模块没有 __version__ 属性也可以使用。
  • 应该是最佳答案,这是获取包版本的唯一可靠方法(如果有的话)
  • 请注意,pkg_resources.get_distrinbution 也并非总是有效。它会发出一些 DistributionNotFound 异常,并带有错误消息,例如:“未找到 'the_package_name' 分布,应用程序需要它”
  • @mjv 您的错误很可能发生,因为 1) 未安装包 2) 您将模块名称而不是包名称传递给 get_distribution 方法
  • 对于 Python importlib_metadata 而不是 pkg_resources,它会更符合 stdlib importlib.metadata 的工作原理。
【解决方案4】:

使用pip show 查找版本!

# in order to get package version execute the below command
pip show YOUR_PACKAGE_NAME | grep Version

【讨论】:

  • 这里没有欢乐! pip: error: No command by the name pip show (maybe you meant "pip install show")
  • 这个答案只有在你需要来自 shell 的包版本时才真正适合。如果您在 Python 中需要它,这将是一个非常糟糕的 hack。无论如何,您可以使用以下命令来提取版本:pip show PACKAGE | awk '/^Version: / {sub("^Version: ", ""); print}'。您可能可以使用更简单的 AWK 脚本,但上述对于任何边缘情况都会更安全。
  • @SamFinnigan pip showpip 1.2.1.post1 中实现。你正在使用一个非常过时的 pip 版本,所以难怪你遇到了麻烦!我目前正在运行 pip 7.1.2。如果有什么东西阻止你更新,你总是可以在本地或 virtualenv 中安装它。
  • 对我有用,谢谢。有些包没有 .__version__ 参数,所以一个更有用。
  • 我的输出似乎有差异:>>print(sklearn.__version__) #returns 0.20.3 >>pip show sklearn #return 0.0;你能澄清一下吗?
【解决方案5】:

更好的方法是:


具体套餐详情

pip show &lt;package_name&gt;

它详细说明了 Package_name、版本、作者、位置等。


$ pip show numpy
Name: numpy
Version: 1.13.3
Summary: NumPy: array processing for numbers, strings, records, and objects.
Home-page: http://www.numpy.org
Author: NumPy Developers
Author-email: numpy-discussion@python.org
License: BSD
Location: c:\users\prowinjvm\appdata\local\programs\python\python36\lib\site-packages
Requires:

更多详情:&gt;&gt;&gt; pip help


pip 应该更新来做到这一点。
pip install --upgrade pip

在 Windows 上推荐的命令是:

python -m pip install --upgrade pip

【讨论】:

  • 我的输出似乎有差异:>>print(sklearn.__version__) #returns 0.20.3 >>pip show sklearn #return 0.0;你能澄清一下吗?
  • 您应该使用pip show scikit-learn 而不是pip show sklearn。 sklearn 是导入时使用的简写形式,不能直接在 pip 中识别,因为 scikit-learn 是完整包 learn not sklearn
【解决方案6】:

在 python3 中用括号括起来打印

>>> import celery
>>> print(celery.__version__)
3.1.14

【讨论】:

  • 并非每个包都有__version__ 属性。
  • 这个答案适用于 python 3 - 这是一种不同的语言。但是,您可以在 python 2 中使用此答案。为此,需要在其他语句之前添加以下行:“from future import print_function”。
  • @user1976 这在 Python 2 中也是有效的语法。 print 的参数周围可以简单地容忍括号,就像 (2)+(3) 评估为 5 一样。当括号内有逗号时,事情可能会变得更有趣,但对于print,它仍然有效。
  • 与旧答案相比,此答案没有提供任何新见解。
【解决方案7】:

module.__version__ 是一个很好的尝试,但它并不总是有效。

如果您不想掏空,并且您正在使用 pip 8 或 9,您仍然可以使用 pip.get_installed_distributions() 从 Python 中获取版本:

更新: 这里的解决方案适用于 pip 8 和 9,但在 pip 10 中,该函数已从 pip.get_installed_distributions 移动到 pip._internal.utils.misc.get_installed_distributions 以明确表明它不适用于外部采用。如果您使用的是 pip 10+,则依赖它不是一个好主意。

import pip

pip.get_installed_distributions()  # -> [distribute 0.6.16 (...), ...]

[
    pkg.key + ': ' + pkg.version
    for pkg in pip.get_installed_distributions()
    if pkg.key in ['setuptools', 'statlib', 'construct']
] # -> nicely filtered list of ['setuptools: 3.3', ...]

【讨论】:

  • 是的,不是所有的包创建者都设置了版本,但是如果你使用pip,这应该总是有效的。
  • 不幸的是,这个解决方案不可行。 Pip 不保证任何进程内 API,只保证通过命令行提供的 API。这种方法不再适用于 pip 10。
【解决方案8】:

前面的答案没有解决我的问题,但是这段代码解决了:

import sys 
for name, module in sorted(sys.modules.items()): 
  if hasattr(module, '__version__'): 
    print name, module.__version__ 

【讨论】:

  • 这只是避免在未定义的情况下尝试打印__version__。如果没有__version__,则不会收到所需包的结果。
  • 如果模块没有__version__属性,这是标准(python.org/dev/peps/pep-0396/#specification),不手动调查是不可能知道版本在哪里以及如何包含的。
【解决方案9】:

使用 dir() 来确定模块是否有 __version__ 属性。

>>> import selenium
>>> dir(selenium)
['__builtins__', '__doc__', '__file__', '__name__',
 '__package__', '__path__', '__version__']
>>> selenium.__version__
'3.141.0'
>>> selenium.__path__
['/venv/local/lib/python2.7/site-packages/selenium']

【讨论】:

  • 正是我在寻找 Selenium 版本 - 神奇的是,我们有了它!与 Python3 一起工作 - 干得好!
  • 这是最接近稳健的解决方案
  • 如果没有__version__怎么办?
【解决方案10】:

在 Python 3.8 版本中,importlib 包中有一个新的 metadata 模块,它也可以做到这一点。

这是来自文档的示例:

>>> from importlib.metadata import version
>>> version('requests')
'2.22.0'

【讨论】:

  • 此方法的好处是在未定义 version 属性时工作。
【解决方案11】:

你可以试试这个:

pip list

这将输出所有包及其版本。 Output

【讨论】:

    【解决方案12】:

    如果上述方法都不起作用,值得在python中尝试以下方法:

    import modulename
    
    modulename.version
    modulename.version_info
    

    Get Python Tornado Version?

    请注意,.version 除了龙卷风之外还为我工作。

    【讨论】:

      【解决方案13】:

      首先将 python, pip 添加到您的环境变量中。以便您可以从命令提示符执行命令。然后简单地给出 python 命令。 然后导入包

      -->import scrapy

      然后打印版本名称

      -->print(scrapy.__version__)

      这肯定行得通

      【讨论】:

      • 正如这里多次讨论的那样,并非每个模块都提供__version__ 属性。
      • 我发现一个包没有显示 pip freeze 但是 .__version_ 工作。感谢发帖。
      【解决方案14】:

      假设我们使用的是 Jupyter Notebook(如果使用终端,请去掉感叹号):

      1) 如果软件包(例如 xgboost)是使用 pip 安装的:

      !pip show xgboost
      !pip freeze | grep xgboost
      !pip list | grep xgboost
      

      2) 如果软件包(例如 caffe)是使用 conda 安装的:

      !conda list caffe
      

      【讨论】:

        【解决方案15】:

        有些模块没有__version__属性,所以最简单的方法是在终端中查看:pip list

        【讨论】:

          【解决方案16】:

          我建议在终端中打开一个python shell(在您感兴趣的python版本中),导入库,并获取其__version__属性。

          >>> import statlib
          >>> statlib.__version__
          
          >>> import construct
          >>> contruct.__version__
          

          注意1:一定要看python版本。如果我们安装了不同版本的python,我们必须在我们感兴趣的python版本中打开终端。例如,用python3.8打开终端可以(肯定会)给出不同版本的库,而不是用@打开987654325@或python2.7

          注意 2:我们避免使用 print 函数,因为它的行为取决于 python2 或 python3。我们不需要它,终端会显示表达式的值。

          【讨论】:

            【解决方案17】:

            为 Windows 用户编写此答案。正如所有其他答案中所建议的,您可以使用以下语句:

            import [type the module name]
            print(module.__version__)      # module + '.' + double underscore + version + double underscore
            

            但是,有些模块即使在使用上述方法后也不会打印它们的版本。所以,你可以简单地做的是:

            1. 打开命令提示符。
            2. 使用 cd [file address] 导航到文件地址/目录,您已在其中安装了 python 和所有支持模块。如果您的系统上只有一个 python,则 PYPI 包通常在目录/文件夹中可见:- Python > Lib > site-packages。
            3. 使用命令“pip install [module name]”并回车。
            4. 这将向您显示一条消息“要求已满足:文件地址\文件夹名称(带有版本)”。
            5. 请参阅下面的屏幕截图,例如:我必须知道名为“Selenium-Screenshot”的预安装模块的版本。它正确显示为 1.5.0:

            【讨论】:

              【解决方案18】:

              总结:

              conda list   
              

              (它将提供所有库以及版本详细信息)。

              还有:

              pip show tensorflow
              

              (它提供了完整的库详细信息)。

              【讨论】:

              • 使用conda list,你可以命名你想要的包,例如conda list statlib
              【解决方案19】:

              这也适用于 Windows 上的 Jupyter Notebook!只要 Jupyter 是从 Git Bash (MingW64) 等符合 bash 的命令行启动的,许多答案中给出的解决方案就可以在 Windows 系统上的 Jupyter Notebook 中使用,只需稍作调整。

              我正在运行 Windows 10 Pro,并通过 Anaconda 安装了 Python,以下代码在我通过 Git Bash 启动 Jupyter 时有效(但在我从 Anaconda 提示符启动时无效)。

              调整:在pip 前面添加一个感叹号 (!) 使其变为!pip

              >>>!pip show lxml | grep Version
              Version: 4.1.0
              
              >>>!pip freeze | grep lxml
              lxml==4.1.0
              
              >>>!pip list | grep lxml
              lxml                               4.1.0                  
              
              >>>!pip show lxml
              Name: lxml
              Version: 4.1.0
              Summary: Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API.
              Home-page: http://lxml.de/
              Author: lxml dev team
              Author-email: lxml-dev@lxml.de
              License: BSD
              Location: c:\users\karls\anaconda2\lib\site-packages
              Requires: 
              Required-by: jupyter-contrib-nbextensions
              

              【讨论】:

                【解决方案20】:

                列出所有包的快速python程序(您可以将其复制到requirements.txt

                from pip._internal.utils.misc import get_installed_distributions
                print_log = ''
                for module in sorted(get_installed_distributions(), key=lambda x: x.key): 
                    print_log +=  module.key + '~=' + module.version  + '\n'
                print(print_log)
                

                输出如下:

                asn1crypto~=0.24.0
                attrs~=18.2.0
                automat~=0.7.0
                beautifulsoup4~=4.7.1
                botocore~=1.12.98
                

                【讨论】:

                  【解决方案21】:

                  (另见https://stackoverflow.com/a/56912280/7262247

                  我发现使用各种可用的工具非常不可靠(包括Jakub Kukul' answer 提到的最好的pkg_resources),因为它们中的大多数并不涵盖所有情况。例如

                  • 内置模块
                  • 模块未安装,只是添加到 python 路径(例如通过您的 IDE)
                  • 同一模块的两个版本可用(python 路径中的一个取代已安装的一个)

                  由于我们需要一种可靠的方法来获取任何包、模块或子模块的版本,我最终写了getversion。使用起来非常简单:

                  from getversion import get_module_version
                  import foo
                  version, details = get_module_version(foo)
                  

                  详情请参阅documentation

                  【讨论】:

                    【解决方案22】:

                    在互联网上搜索后,试图弄清楚如何确保跨操作系统和 python 版本运行的模块版本(显然 python_is_horrible.__version__ 不是 2 中的东西?)...实际上这些答案都不适用于我的场景...

                    然后我想了一分钟,意识到了基础......在失败了大约 30 分钟之后......

                    假设模块已经安装并且可以导入


                    3.7

                    >>> import sys,sqlite3
                    >>> sys.modules.get("sqlite3").version
                    '2.6.0'
                    >>> ".".join(str(x) for x in sys.version_info[:3])
                    '3.7.2'
                    

                    2.7

                    >>> import sys,sqlite3
                    >>> sys.modules.get("sqlite3").version
                    '2.6.0'
                    >>> ".".join(str(x) for x in sys.version_info[:3])
                    '2.7.11'
                    

                    原来如此……

                    【讨论】:

                    • 注意:不是所有的包都有.version属性sys.modules.get("numpy").version
                    • @HashRocketSyntax 对于我的一生我无法理解为什么这两者以及 python 模块/包的导入模型没有更多的一致性。持续头痛
                    【解决方案23】:

                    获取当前模块中导入的非标准(pip)模块列表:

                    [{pkg.key : pkg.version} for pkg in pip.get_installed_distributions() 
                       if pkg.key in set(sys.modules) & set(globals())]
                    

                    结果:

                    >>> import sys, pip, nltk, bs4
                    >>> [{pkg.key : pkg.version} for pkg in pip.get_installed_distributions() if pkg.key in set(sys.modules) & set(globals())]
                    [{'pip': '9.0.1'}, {'nltk': '3.2.1'}, {'bs4': '0.0.1'}]
                    

                    注意:

                    此代码来自此页面和How to list imported modules? 的解决方案

                    【讨论】:

                      【解决方案24】:

                      如果您的 prod 系统变得难以理解,因此它既没有 pip 也没有 conda,这里是 pip freeze 的 bash 替代品:

                      ls /usr/local/lib/python3.8/dist-packages | grep info | awk -F "-" '{print $1"=="$2}' | sed 's/.dist//g'
                      

                      (确保将 dist-packages 文件夹更新为当前的 python 版本并忽略不一致的名称,例如下划线与破折号)。

                      示例打印输出:

                      Flask==1.1.2
                      Flask_Caching==1.10.1
                      gunicorn==20.1.0
                      [..]
                      

                      【讨论】:

                        【解决方案25】:

                        Jakub Kukul's answer 的基础上,我找到了一种更可靠的方法来解决这个问题。

                        这种方法的主要问题是需要“按常规”安装包(不包括使用 pip install --user),或者在 Python 初始化时位于系统 PATH 中。

                        要解决这个问题,您可以使用pkg_resources.find_distributions(path_to_search)。如果path_to_search 在系统路径中,这基本上会搜索可导入的发行版。

                        我们可以像这样遍历这个生成器:

                        avail_modules = {}
                        distros = pkg_resources.find_distributions(path_to_search)
                        for d in distros:
                            avail_modules[d.key] = d.version
                        

                        这将返回一个字典,其中模块作为键​​,它们的版本作为值。这种方法可以扩展到比版本号更多的地方。

                        感谢 Jakub Kukul 指出正确的方向

                        【讨论】:

                          【解决方案26】:

                          我自己在一个受到严格限制的服务器环境中工作,不幸的是,这里的解决方案都不适合我。可能没有适合所有人的手套解决方案,但我通过在我的脚本中读取 pip freeze 的终端输出并将模块标签和版本存储在字典中找到了一个快速的解决方法。

                          import os
                          os.system('pip freeze > tmpoutput')
                          with open('tmpoutput', 'r') as f:
                              modules_version = f.read()
                            
                          module_dict = {item.split("==")[0]:item.split("==")[-1] for item in modules_versions.split("\n")}
                          

                          通过传递模块标签键来检索模块的版本,例如:

                          >>  module_dict["seaborn"]
                          '0.9.0'
                          

                          【讨论】:

                            【解决方案27】:

                            这是一个小 bash 程序,用于获取 python 环境中任何包的版本。只需将其复制到您的 /usr/bin 并为其提供 exec 权限:

                            #!/bin/bash
                            packageName=$1
                            
                            python -c "import ${packageName} as package; print(package.__version__)"
                            

                            然后你可以在终端中运行它,假设你将脚本命名为py-check-version:

                            py-check-version whatever_package
                            

                            【讨论】:

                              【解决方案28】:

                              您可以简单地使用subprocess.getoutput(python3 --version)

                              import subprocess as sp
                              print(sp.getoutput(python3 --version))
                              
                              # or however it suits your needs!
                              py3_version = sp.getoutput(python3 --version)
                              
                              def check_version(name, version):...
                              
                              check_version('python3', py3_version)
                              

                              有关不依赖于__version__ 属性的更多信息和方法:

                              Assign output of os.system to a variable and prevent it from being displayed on the screen

                              您也可以使用subprocess.check_output(),它会在子进程返回退出代码 0 以外的任何内容时引发错误:

                              https://docs.python.org/3/library/subprocess.html#check_output()

                              【讨论】:

                              • 这是python版本本身,问题是询问包版本。
                              【解决方案29】:

                              你可以先安装一些这样的包,然后检查它的版本

                              pip install package
                              import package
                              print(package.__version__)
                              

                              它应该给你包版本

                              【讨论】:

                              • __version__ 属性已在此处的许多其他答案中提及,此答案提供了哪些新信息?
                              猜你喜欢
                              • 2011-03-14
                              • 1970-01-01
                              • 1970-01-01
                              • 2010-10-17
                              • 2010-12-30
                              • 1970-01-01
                              • 2012-06-10
                              • 1970-01-01
                              相关资源
                              最近更新 更多