在运行时检查Python模块版本

Gru*_*uff 109 python module version

许多第三方Python模块都有一个属性,它保存模块的版本信息(通常类似于module.VERSION或者module.__version__),但有些则没有.

这些模块的特定示例是libxslt和libxml2.

我需要检查在运行时是否正在使用这些模块的正确版本.有没有办法做到这一点?

一个潜在的解决方案是在运行时读取源代码,哈希它,然后将它与已知版本的哈希值进行比较,但那是令人讨厌的.

有更好的解决方案吗?

Eni*_*rry 233

使用pkg_resources.从PyPI安装的任何东西至少应该有一个版本号.

>>> import pkg_resources
>>> pkg_resources.get_distribution("blogofile").version
'0.7.1'
Run Code Online (Sandbox Code Playgroud)

  • 另请注意,包名必须是PyPI条目的名称.所以像"pkg_resources.get_distribution('MySQLdb').version"这样的东西不起作用,但是"pkg_resources.get_distribution('mysql-python').version"会. (8认同)
  • 如果有人想知道如何制作`__version__`属性:http://stackoverflow.com/q/17583443/562769 (3认同)

Ric*_*eur 6

一些想法:

  1. 尝试检查所需版本中是否存在的功能.
  2. 如果没有函数差异,请检查函数参数和签名.
  3. 如果您无法从功能签名中找到它,请在导入时设置一些存根调用并检查其行为.


Mar*_*ddy 6

我会远离哈希.正在使用的libxslt版本可能包含某些类型的补丁,这些补丁不会影响您对它的使用.

作为替代方案,我建议你不要在运行时检查(不知道这是否是一个硬性要求).对于我编写的具有外部依赖项(第三方库)的python内容,我编写了一个脚本,用户可以运行该脚本来检查他们的python安装,看看是否安装了相应版本的模块.

对于没有定义'version'属性的模块,您可以检查它包含的接口(类和方法),看它们是否与它们期望的接口匹配.然后在您正在使用的实际代码中,假设第三方模块具有您期望的接口.


Jak*_*kul 6

如果您使用的是 python,>=3.8您可以使用内置库中的模块。要检查包的版本(在本例中lxml)运行:

>>> from importlib.metadata import version
>>> version('lxml')
'4.3.1'
Run Code Online (Sandbox Code Playgroud)

此功能也已移植到旧版本的 python ( <3.8) 中,但您需要先安装一个单独的库:

pip install importlib_metadata
Run Code Online (Sandbox Code Playgroud)

然后检查包的版本(在本例中lxml)运行:

>>> from importlib_metadata import version
>>> version('lxml')
'4.3.1'
Run Code Online (Sandbox Code Playgroud)

请记住,这仅适用于从 PyPI 安装的包。此外,您必须将包名称作为参数传递给该version方法,而不是该包提供的模块名称(尽管它们通常相同)。