2012-02-10 95 views
77

當我做pip凍結時,我看到大量沒有明確安裝的Python軟件包,例如,確定使用pip安裝的python軟件包的依賴關係

$ pip freeze 
Cheetah==2.4.3 
GnuPGInterface==0.3.2 
Landscape-Client==11.01 
M2Crypto==0.20.1 
PAM==0.4.2 
PIL==1.1.7 
PyYAML==3.09 
Twisted-Core==10.2.0 
Twisted-Web==10.2.0 
(etc.) 

有沒有辦法讓我確定爲什麼pip安裝這些特定的相關軟件包?換句話說,我如何確定將這些包作爲依賴包的父包?

例如,我可能想要使用Twisted,並且我不想依賴於包,除非我知道更多關於不意外卸載或升級它的信息。

回答

85

你可以嘗試pipdeptree這顯示依賴關係樹結構如:

$ pipdeptree 
Lookupy==0.1 
wsgiref==0.1.2 
argparse==1.2.1 
psycopg2==2.5.2 
Flask-Script==0.6.6 
    - Flask [installed: 0.10.1] 
    - Werkzeug [required: >=0.7, installed: 0.9.4] 
    - Jinja2 [required: >=2.4, installed: 2.7.2] 
     - MarkupSafe [installed: 0.18] 
    - itsdangerous [required: >=0.21, installed: 0.23] 
alembic==0.6.2 
    - SQLAlchemy [required: >=0.7.3, installed: 0.9.1] 
    - Mako [installed: 0.9.1] 
    - MarkupSafe [required: >=0.9.2, installed: 0.18] 
ipython==2.0.0 
slugify==0.0.1 
redis==2.9.1 

爲了得到它運行:由@注意:

pip install pipdeptree 


編輯埃斯特萬在評論中也可以列出與之相反的樹-r或單個封裝-p <package_name>所以要查找安裝WERKZEUG你可以運行:

$ pipdeptree -r -p Werkzeug 
Werkzeug==0.11.15 
    - Flask==0.12 [requires: Werkzeug>=0.7] 
+4

我相信要完全回答你需要運行的@mark的問題: 'pipdeptree -r' 「以相反的方式顯示依賴關係樹,即子依賴項列出了需要它們的包列表在他們下面。「 – Esteban 2016-07-26 21:28:33

+0

類似項目:https://github.com/rbanffy/pip-chill – 2017-06-23 04:32:51

+0

如何查看所有PyPi軟件包的反轉樹,而不僅僅是本地安裝的軟件包? – Tijme 2017-07-18 16:16:56

2

首先pip freeze顯示所有當前安裝的軟件包Python,不一定使用PIP。

其次Python包包含有關從屬包的信息以及required versions。您可以使用方法described here查看特定pkg的依賴關係。在升級軟件包時,PIP等安裝程序腳本將爲您處理升級依賴項。

爲了解決軟件包的更新問題,我推薦使用PIP requirements files。您可以定義您需要的軟件包和版本,並使用pip install一次性安裝它們。

57

pip show命令會顯示需要什麼樣的包指定程序包(注意,必須已安裝指定的包):

$ pip show specloud 

Package: specloud 
Version: 0.4.4 
Requires: 
nose 
figleaf 
pinocchio 

pip show在PIP版本1.4rc5

+1

'點子show'在1.4rc5版本推出,而在存在(目前爲寫作)1.4.1 – drevicko 2013-10-23 02:52:04

+8

這並不完全回答我的問題,因爲它顯示了特定包裹的孩子(依賴),而不是父母。但是使用這個命令很容易將一些東西放在一起來檢查每個包的依賴關係。所以,例如,我可以確定哪個安裝包需要PyYAML。 – 2014-02-21 09:27:09

+4

根據我以前的評論,這個shell命令會拋出我安裝的每個軟件包的所有依賴關係:$ pip freeze | grep -v「\ -e」| sed s /\=\=.*// | awk'系統(「pip show」$ 1)' – 2014-02-21 15:15:11

13

被介紹爲我最近在hn thread上說過,我會推薦以下內容:

有一個帶註釋的文件requirements.txt

## this is needed for whatever reason 
package1 

安裝您的依賴關係:pip install -r requirements.txt。 現在你得到你的依賴關係的完整列表,與pip freeze -r requirements.txt

## this is needed for whatever reason 
package1==1.2.3 

## The following requirements were added by pip --freeze: 
package1-dependency1==1.2.3 
package1-dependency1==1.2.3 

這可以讓你保持你的文件結構與意見,很好地從你的依賴的依賴分離你的依賴。這樣,你就會有一個更加美好的時間,你需要刪除其中的一個:)

注意以下幾:

  • 你可以有一個乾淨的requirements.raw版本控制來重建完整的requirements.txt
  • 小心git網址在過程中被蛋名取代。
  • 依賴關係的依賴關係仍按字母順序排序,因此您不直接知道哪個包需要哪個包,但此時您並不真正需要它。
  • 使用pip install --no-install <package_name>列出具體要求。
  • 如果您不需要,請使用virtualenv
+0

我只是不明白爲什麼這個'pip freeze -r requirements.txt''沒有被廣泛使用。對於維護依賴關係和子依賴關係非常有用。 – 2017-07-03 08:43:28

5

您也可以使用一行命令,它將需求中的包傳遞到pip顯示。

cut -d'=' -f1 requirements.txt | xargs pip show 
+1

一般來說,你不能像requirements.txt的格式比' == '複雜。 – 2016-03-25 07:33:10

0

(解決方法,而不是真正的答案)

有同樣的問題,有沒有LXML安裝和我想知道誰需要LXML。 不需要lxml。最終繞過這個問題。

  1. 注意到我的網站包放置在哪裏。

  2. 去那裏和遞歸grep的導入(最後grep的 - 反向匹配用於刪除lxml自己的文件考慮)。

是的,沒有一個答案,如何使用PIP做到這一點,但我沒有得到任何的成功在這裏的建議的,無論出於何種原因。

site-packages me$ egrep -i --include=*.py -r -n lxml . | grep import | grep --invert-match /lxml/ 
1

我寫了一個快速腳本來解決這個問題。以下腳本將顯示任何給定包的父(依賴)包。通過這種方式,您可以確保升級或安裝任何特定軟件包是安全的。它可以用來如下:dependants.py PACKAGENAME

#!/usr/bin/python3 
# -*- coding: utf-8 -*- 

"""Find dependants of a Python package""" 

import logging 
import pip 
import pkg_resources 
import sys 

__program__ = 'dependants.py' 


def get_dependants(target_name): 
    for package in pip.get_installed_distributions(): 
     for requirement_package in package.requires(): 
      requirement_name = requirement_package.project_name 
      if requirement_name == target_name: 
       package_name = package.project_name 
       yield package_name 


# configure logging 
logging.basicConfig(format='%(levelname)s: %(message)s', 
        level=logging.INFO) 

try: 
    target_name = sys.argv[1] 
except IndexError: 
    logging.error("missing package name") 
    sys.exit(1) 

try: 
    pkg_resources.get_distribution(target_name) 
except pkg_resources.DistributionNotFound: 
    logging.error("'%s' is not a valid package", target_name) 
    sys.exit(1) 

print(list(get_dependants(target_name))) 
相關問題