如何获取Python依赖/模块的版本,包括通过subprocess.Popen调用的外部应用程序?

2 投票
2 回答
927 浏览
提问于 2025-04-15 18:26

我有一组Python脚本,常常在不同的机器上运行,这些脚本依赖于一些外部库,还有一些通过 subprocess.Popen 启动的其他应用程序。

正如预期的那样,输出结果会因为安装的模块和应用程序的版本不同而有所变化。为了应对这个问题,我想记录下运行时使用的版本。

为此,我考虑了以下几个步骤:

  1. 使用 modulefinder 来收集依赖项。
  2. 尝试调用 module.__version__module.get_version() 或其他常见的方法来获取每个收集到的模块的版本信息。
  3. 收集所有对 subprocess.Popen 的调用,并尝试通过解析输出,使用不同的参数来获取版本号,比如 -version、-v、-?、-h 等等。

步骤2和步骤3可以通过使用特定发行版的工具(在我这里是 Debian)来大大改进,比如使用 dpkg 来获取已安装包的版本。缺点是这不仅依赖于操作系统,还依赖于特定的发行版。不过我意识到,最初的方法效率极低且容易出错,甚至可能根本无法正常工作。

所以我的问题是,是否有现成的包可以解决这个问题,或者有没有人有更好的建议来实现这个功能?

2 个回答

0

如果你不想直接检查你的Python程序的依赖关系,而且你是在Linux或Unix系统上运行的话,可以用一个叫做 memoize.py 的工具来包装你的程序。这个 memoize.py 工具会使用 strace,也就是“系统跟踪”,来监控你的程序生成的所有系统读写命令,然后把这些依赖关系存储到一个文件里。memoize.py 还可以作为一个库使用,这样你就可以在你的程序内部调用它的功能,并以Python的数据结构获取依赖关系。

1

两年过去了,出现了一些新工具。

现在有了 pip freeze,特别是和 virtualenv 一起使用,可以解决之前提到的第1和第2点问题。

对于外部应用程序,我不得不使用系统的包管理工具(比如 apt-file、dpkg、qlist、emerge 等,具体取决于系统),这过程中也遇到了不少麻烦。

我还是想提一下罗斯的回答,因为它达到了我想要的效果。不过从我的角度来看,它收集了比实际需要的依赖项多了很多。

撰写回答