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
,但仍然设法安装numpy
、pytz
等......有没有更好的方法来自动收集完整的列表依赖项?
某处是否有预先存在的数据库?我是在重复现有的工作吗?
是否存在用于其他具有分发系统的语言(R、Clojure 等...)的类似且易于访问的数据库?
【问题讨论】:
你的问题,就目前而言,实际上太宽泛了。不要在帖子中提出太多问题,并保持实用性和可回答性。你的观点 3. 邀请辩论和购物清单,而不是具体的答案。 【参考方案1】:您应该查看install_requires
字段而不是,请参阅New and changed setup
keywords。
requires
被认为是一个过于模糊的字段,无法依赖依赖项安装。此外,还有setup_requires
和test_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 包依赖树的主要内容,如果未能解决你的问题,请参考以下文章