如何在Python中以编程方式获取已安装模块的版本?

4 投票
2 回答
1441 浏览
提问于 2025-04-16 23:42

对于这些模块:

required_modules = ['nose', 'coverage', 'webunit', 'MySQLdb', 'pgdb', 'memcache']

以及程序:

required_programs = ['psql', 'mysql', 'gpsd', 'sox', 'memcached']

大概是这样的:

# Report on the versions of programs installed
for module in required_modules:
    try:
        print module.__version__
    except:
        exit

2 个回答

-1

我发现使用各种工具来获取版本信息并不太可靠(包括moraes的回答中提到的最好用的pkg_resources),因为大多数工具并不能覆盖所有情况。

在Python中,版本号可能会出现在不同的地方,具体取决于情况:

  • 对于模块和包,版本号通常在可选的__version__属性中,这是PEP396推荐的。如果子包和子模块没有这个属性,默认情况下应该继承父包的版本号。

  • 对于分发的模块和包,版本号在Version元数据字段中,这个字段的位置由PEP345规定:

    • 对于构建的轮子分发(PEP427),版本号在dist-info目录中,同时也在dist-info文件夹的名称中。
    • 对于构建的蛋分发(setuptools的旧格式),版本号在egg-info目录中,同样也在egg-info文件夹的名称中。
  • 最后,对于内置模块和包,默认版本应该继承自Python系统的版本,除非被覆盖。

此外,在运行时(也就是你需要这个版本号的时候),包和模块可能会:

  • 已经被导入,或者没有被导入
  • 已经构建并通过pip安装(无论是否在调试模式下),或者仅仅是添加到PYTHON PATH(sys.path)中
  • 没有构建并添加到PYTHON PATH(sys.path)中

这种多样的设置使得现有的解决方案很难处理这个问题的所有方面。pkg_resources可能是目前获取版本信息的最佳方式,但例如当一个包是解压的轮子并添加到PYTHON PATH时,它就无法工作。此外,它也不支持内置模块。

因为我们需要一个可靠的方法来获取任何包、模块或子模块的版本,我最终写了getversion。它实现了一系列策略,直到找到有效的方法。

使用起来非常简单:

from getversion import get_module_version

# Get the version of an imported module
from xml import dom
version, details = get_module_version(dom)

特别是details提供了关于如何获取版本标志的有用提示:

> print(details)
Version '3.7.3.final.0' found for module 'xml.dom' by strategy 'get_builtin_module_version', after the following failed attempts:
 - Attempts for module 'xml.dom':
   - <get_module_version_attr>: module 'xml.dom' has no attribute '__version__'
 - Attempts for module 'xml':
   - <get_module_version_attr>: module 'xml' has no attribute '__version__'
   - <get_version_using_pkgresources>: Invalid version number: None
   - <get_builtin_module_version>: SUCCESS: 3.7.3.final.0

有关详细信息,请查看文档。我从这个页面复制了上面的关于问题的细节。

3

很遗憾,并不是所有的模块都有module.__version__这个属性。

一个解决办法是使用包管理工具。当你通过easy_installpip安装一个库时,它会记录下你安装的版本。然后你可以这样做:

import pkg_resources
version = pkg_resources.get_distribution("nose").version

撰写回答