Python 包依赖树

Posted

技术标签:

【中文标题】Python 包依赖树【英文标题】:Python package dependency tree 【发布时间】:2013-03-20 11:28:15 【问题描述】:

我想分析一下 Python 包的依赖树。我怎样才能获得这些数据?

我已经知道的事情

    setup.py 有时包含一个列出包依赖关系的requires 字段 PyPi 是 Python 包的在线存储库 PyPi 有一个 API

我不知道的事情

    PyPi 上很少有项目(大约 10%)在 requires 字段中明确列出依赖项,但 pip/easy_install 仍然设法下载正确的包。我错过了什么?例如流行的统计计算库pandas,没有列出requires,但仍然设法安装numpypytz等......有没有更好的方法来自动收集完整的列表依赖项? 某处是否有预先存在的数据库?我是在重复现有的工作吗? 是否存在用于其他具有分发系统的语言(R、Clojure 等...)的类似且易于访问的数据库?

【问题讨论】:

你的问题,就目前而言,实际上太宽泛了。不要在帖子中提出太多问题,并保持实用性和可回答性。你的观点 3. 邀请辩论和购物清单,而不是具体的答案。 【参考方案1】:

您应该查看install_requires 字段而不是,请参阅New and changed setup keywords。

requires 被认为是一个过于模糊的字段,无法依赖依赖项安装。此外,还有setup_requirestest_requires 字段用于setup.py 和运行测试所需的依赖项。

当然,依赖图之前已经分析过了;来自blog article by Olivier Girardot 的这张梦幻般的图片:

图像链接到图形的交互式版本。

【讨论】:

嗯,它一个非常漂亮的图表! 这张图太棒了。 图这么漂亮,看不懂。 还有 requires_dist 可以在 json api 中看到:pypi.python.org/pypi/Django/json 有像密码学这样的包使用 `install_requires' 并且该信息在 api 中没有:pypi.python.org/pypi/cryptography/json跨度> 【参考方案2】:

使用pip 之类的工具,您可以列出每个包的所有要求。

命令是:

pip install --no-install package_name

您可以在脚本中重复使用部分 pip。负责解析需求的部分是模块pip.req

【讨论】:

我喜欢在 Python 中使用 pip 的想法。如果我已经安装了软件包,命令行界面会失败。如何直接使用 Python 代码查找特定包的依赖项? --no-install 已弃用。【参考方案3】:

以下是使用 python pip 包以编程方式执行此操作的方法:

from pip._vendor import pkg_resources  # Ensure pip conf index-url pointed to real PyPi Index

# Get dependencies from pip 
package_name = 'Django'
try:
    package_resources = pkg_resources.working_set.by_key[package_name.lower()] # Throws KeyError if not found
    dependencies = package_resources._dep_map.keys() + ([str(r) for r in package_resources.requires()])
    dependencies = list(set(dependencies))
except KeyError:
    dependencies = []

以下是如何从 PyPi API 获取依赖项:

import requests
import json
package_name = 'Django'
# Package info url
PYPI_API_URL = 'https://pypi.python.org/pypi/package_name/json'
package_details_url = PYPI_API_URL.format(package_name=package_name)
response = requests.get(package_details_url)
data = json.loads(response.content)
if response.status_code == 200:
    dependencies = data['info'].get('requires_dist')
    dependencies2 = data['info'].get('requires')
    dependencies3 = data['info'].get('setup_requires')
    dependencies4 = data['info'].get('test_requires')
    dependencies5 = data['info'].get('install_requires')
    if dependencies2:
        dependencies.extend(dependencies2)
    if dependencies3:
        dependencies.extend(dependencies3)
    if dependencies4:
        dependencies.extend(dependencies4)
    if dependencies5:
        dependencies.extend(dependencies5)
    dependencies = list(set(dependencies))

您可以使用递归来调用依赖项的依赖项以获得完整的树。干杯!

【讨论】:

以上是关于Python 包依赖树的主要内容,如果未能解决你的问题,请参考以下文章

查看jar包依赖树

Gradle依赖树查看

有啥方法可以显示 pip 包的依赖树吗?

Python 一键安装全部依赖包

python离线批量安装依赖包

Python项目requirements.txt依赖包如何生成?