如何查找Python包的依赖项


103

如何以编程方式获取Python软件包的依赖关系列表?

标准setup.py已记录了这些内容,但是我找不到 Python或命令行访问它的简便方法。

理想情况下,我正在寻找类似的东西:

$ pip install somepackage --only-list-deps
kombu>=3.0.8
billiard>=3.3.0.13
boto>=2.26

要么:

>>> import package_deps
>>> package = package_deps.find('somepackage')
>>> print package.dependencies
['kombu>=3.0.8', 'billiard>=3.3.0.13', 'boto>=2.26']

注意,我不是在谈论导入包和查找所有引用的模块。尽管这可能找到大多数相关软件包,但无法找到所需的最低版本号。那只存储在setup.py中。


这里有很多答案,表明将pip导入以便在程序中使用。pip文档强烈建议不要使用pip。万一这些解决方案被用于任何重要的事情,请记住一些事情。
Jordan Mackie

Answers:


97

除了pip show [package name]命令,还有pipdeptree

做就是了

$ pip install pipdeptree

然后跑

$ pipdeptree

它会以树形形式显示您的依赖关系,例如,

flake8==2.5.0
  - mccabe [required: >=0.2.1,<0.4, installed: 0.3.1]
  - pep8 [required: !=1.6.0,>=1.5.7,!=1.6.1,!=1.6.2, installed: 1.5.7]
  - pyflakes [required: >=0.8.1,<1.1, installed: 1.0.0]
ipdb==0.8
  - ipython [required: >=0.10, installed: 1.1.0]

该项目位于https://github.com/naiquevin/pipdeptree,您还将在其中找到使用信息。


7
pipdeptree显示所有 已安装软件包的依赖性,而不仅仅是给定软件包的依赖性。尽管可以过滤其--json输出,但它仍取决于已安装的软件包。
sschuberth's

是的,但是当您想了解为什么安装了不在您的软件包中的软件包时,答案仍然很有用requirements.txt:)
beruic

3
另外,您可以使用此-p选项仅选择要浏览其依赖项的一些软件包。
Zaccharie Ramzi

2
pipdeptree在优化时非常有帮助requirements.txt$ pipdeptree | grep -P '^\w+' 这仅输出顶级程序包。更多信息在这里
Lead Developer

63

尝试在中使用show命令pip,例如:

$ pip show tornado
---
Name: tornado
Version: 4.1
Location: *****
Requires: certifi, backports.ssl-match-hostname

更新(检索指定版本的部门):

from pip._vendor import pkg_resources


_package_name = 'somepackage'
_package = pkg_resources.working_set.by_key[_package_name]

print([str(r) for r in _package.requires()])  # retrieve deps from setup.py

Output: ['kombu>=3.0.8', 
         'billiard>=3.3.0.13', 
         'boto>=2.26']

1
那告诉你软件包的版本,而不是它的依赖关系 ; 他们只是被列出。
jonrsharpe 2015年

参见Requires部分
Alex Lisovoy,2015年

3
是的,但是没有显示“所需的最低版本号”,这是OP所要求的:
jonrsharpe 2015年

1
不知何故对我来说$ pip3 show beautifulsoup4是空的-beautifulsoup4 Requires: 依赖什么吗?
xealits

4
@PythonJin,是的,显然它只使用标准软件包。.我对此感到有些惊讶。干得好beautifulsoup4
xealits '16

6

这里有很多答案,表明将pip导入以便在程序中使用。pip文档强烈建议不要使用pip

实际上pkg_resources,您可以pkg_resources直接导入并使用相同的逻辑(而不是通过pip导入进行访问)(这实际上是pip docs中链接的建议解决方案之一,适用于希望以编程方式查看程序包元信息的任何人)。

import pkg_resources

_package_name = 'yourpackagename'

def get_dependencies_with_semver_string():
    package = pkg_resources.working_set.by_key[_package_name]
    return [str(r) for r in package.requires()]

如果您在查找确切的软件包名称时遇到麻烦,可以WorkingSet通过pkg_resources.working_setImplements 返回的实例,__iter__以便将它们全部打印出来,并希望在其中找到它们:)

import pkg_resources

def print_all_in_working_set():
    ws = pkg_resources.working_set
    for package_name in ws:
        print(ws)

这适用于python 2和python 3(尽管您需要调整python2的打印语句)


3

(这是一个传统的答案,应该避免使用现代PIP版本,并在此引用旧PIP版本)。Alex的回答很好(+1)。在python中:

pip._vendor.pkg_resources.working_set.by_key['twisted'].requires()

应该返回类似

[Requirement.parse('zope.interface>=3.6.0')]

包装的名称在哪里是扭曲的,您可以在字典中找到它:

pip._vendor.pkg_resources.WorkingSet().entry_keys

列出所有:

dict = pip._vendor.pkg_resources.WorkingSet().entry_keys
for key in dict:
    for name in dict[key]:
        req =pip._vendor.pkg_resources.working_set.by_key[name].requires()
        print('pkg {} from {} requires {}'.format(name,
                                                  key,
                                                  req))

应该给你这样的清单:

pkg pyobjc-framework-syncservices from /System/Library/Frameworks/Python.framework/Versions/2.7/Extras/lib/python/PyObjC requires [Requirement.parse('pyobjc-core>=2.5.1'), Requirement.parse('pyobjc-framework-Cocoa>=2.5.1'), Requirement.parse('pyobjc-framework-CoreData>=2.5.1')]

最近的版本有变化吗?该_vendor属性似乎在pip版本中不存在19.1.1(编辑:好的,它似乎已经移动到pkg_resources了最新的python版本中的软件包!)
Prahlad Yeri,

是的,情况已经改变,我将考虑更新或删除它,以支持下面的建议。
csseller

从我的角度来看,亚历克斯的回答仅部分更好(嗯,pip show部分很好,其余部分则不好)。请使用pip showpipdeptree或直接使用setuptools ' 查看Jordan Mackie的答案pkg_resources
sinoroc


1

根据python中的这篇文章尝试以下操作:

import pip 
installed_packages = pip.get_installed_distributions()
installed_packages_list = sorted(["%s==%s" % (i.key, i.version)
     for i in installed_packages]) 
print(installed_packages_list)

它将显示为:

['behave==1.2.4', 'enum34==1.0', 'flask==0.10.1', 'itsdangerous==0.24', 
 'jinja2==2.7.2', 'jsonschema==2.3.0', 'markupsafe==0.23', 'nose==1.3.3', 
 'parse-type==0.3.4', 'parse==1.6.4', 'prettytable==0.7.2', 'requests==2.3.0',
 'six==1.6.1', 'vioozer-metadata==0.1', 'vioozer-users-server==0.1', 
 'werkzeug==0.9.4']
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.