2012-02-10 34 views
77

Khi tôi đóng băng, tôi thấy số lượng lớn các gói Python mà tôi không cài đặt rõ ràng, ví dụ:Xác định mối quan hệ phụ thuộc đối với các gói python được cài đặt với pip

$ 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.) 

Có cách nào để tôi xác định lý do pip cài đặt các gói phụ thuộc cụ thể này không? Nói cách khác, làm cách nào để xác định gói cha mẹ có các gói này là phụ thuộc?

Ví dụ: tôi có thể muốn sử dụng Twisted và tôi không muốn phụ thuộc vào gói cho đến khi tôi biết thêm về việc vô tình gỡ cài đặt hoặc nâng cấp nó.

Trả lời

85

Bạn có thể thử pipdeptree hiển thị phụ thuộc như một cấu trúc cây ví dụ:

$ 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 

Để có được nó chạy:

pip install pipdeptree 


EDIT: như ghi nhận của @ Esteban trong các ý kiến ​​bạn cũng có thể liệt kê cây ngược lại -r hoặc cho một gói duy nhất với -p <package_name> như vậy để tìm thấy những gì được cài đặt Werkzeug bạn có thể chạy:

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

Tôi tin rằng câu trả lời đầy đủ của @mark bạn sẽ cần phải chạy: 'pipdeptree -r' " Hiển thị cây phụ thuộc theo nghĩa ngược thời trang. Các phụ thuộc phụ được liệt kê với danh sách các gói cần chúng ở dưới chúng." – Esteban

+0

Dự án tương tự: https://github.com/rbanffy/pip-chill –

+0

Làm cách nào bạn có thể xem cây ngược lại cho tất cả các gói PyPi, không chỉ các gói được cài đặt cục bộ? – Tijme

2

Trước hết, pip freeze hiển thị tất cả các gói hiện được cài đặt Python, không nhất thiết phải sử dụng PIP.

Các gói Python thứ hai chứa thông tin về các gói phụ thuộc cũng như required versions. Bạn có thể thấy phụ thuộc của pkg cụ thể bằng cách sử dụng các phương thức described here. Khi bạn nâng cấp một gói, kịch bản trình cài đặt như PIP sẽ xử lý việc nâng cấp các phụ thuộc cho bạn.

Để giải quyết việc cập nhật các gói, tôi khuyên bạn nên sử dụng PIP requirements files. Bạn có thể xác định những gói và phiên bản nào bạn cần, và cài đặt chúng cùng một lúc bằng pip install.

57

Lệnh pip show sẽ hiển thị những gì gói được yêu cầu cho gói quy định (lưu ý rằng mức khoán quy định đã phải được cài đặt):

$ pip show specloud 

Package: specloud 
Version: 0.4.4 
Requires: 
nose 
figleaf 
pinocchio 

pip show đã được giới thiệu trong phiên bản pip 1.4rc5

+1

'show' pip đã được giới thiệu trong phiên bản 1.4rc5, và hiện diện trong (hiện tại như các văn bản) 1.4.1 – drevicko

+8

này không trả lời câu hỏi của tôi một cách chính xác, bởi vì nó cho thấy trẻ em (phụ thuộc) cho một gói cụ thể, thay vì cha mẹ. Nhưng thật dễ dàng để ném thứ gì đó lại với nhau để kiểm tra sự phụ thuộc của từng gói, sử dụng lệnh này. Vì vậy, ví dụ, tôi có thể xác định gói cài đặt yêu cầu PyYAML. –

+4

Theo bình luận trước của tôi, lệnh shell này sẽ loại bỏ tất cả các phụ thuộc cho mỗi gói đã cài đặt của tôi: $ pip freeze | grep -v "\ -e" | sed s /\=\=.*// | awk 'system ("pip show" $ 1)' –

13

Như tôi gần đây đã nói trên hn thread, tôi sẽ đề xuất những điều sau:

Đã nhận xét requirements.txt tệp với phụ thuộc chính của bạn:

## this is needed for whatever reason 
package1 

Cài đặt phụ thuộc của bạn: pip install -r requirements.txt. Bây giờ bạn có danh sách đầy đủ các phụ thuộc của bạn với 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 

này cho phép bạn để giữ cấu trúc tập tin của bạn với các ý kiến, độc đáo tách phụ thuộc của bạn khỏi sự phụ thuộc của sự phụ thuộc của bạn. Bằng cách này bạn sẽ có một thời gian rất đẹp trong ngày bạn cần phải loại bỏ một trong số họ :)

Lưu ý những điều sau:

  • Bạn có thể có một sạch requirements.raw với điều khiển phiên bản để xây dựng lại đầy đủ requirements.txt của bạn.
  • Hãy coi chừng các url git được thay thế bằng tên trứng trong quá trình.
  • Sự phụ thuộc của các phụ thuộc của bạn vẫn được sắp xếp theo thứ tự bảng chữ cái, do đó bạn không trực tiếp biết được gói nào được yêu cầu theo gói nào nhưng tại thời điểm này bạn không thực sự cần nó.
  • Sử dụng pip install --no-install <package_name> để liệt kê các yêu cầu cụ thể.
  • Sử dụng virtualenv nếu bạn không làm như vậy.
+0

Tôi chỉ không hiểu lý do tại sao "pip freeze -r requirements.txt'' này không được sử dụng rộng rãi. Rất hữu ích cho việc duy trì phụ thuộc và phụ thuộc phụ. –

5

Bạn cũng có thể sử dụng lệnh một dòng để gói các gói theo yêu cầu để hiển thị pip.

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

Nói chung bạn không thể định dạng của requirements.txt phức tạp hơn ' == '. –

0

(workaround, không câu trả lời đúng)

Đã cùng một vấn đề, với lxml không cài đặt và tôi muốn biết ai cần lxml. Không phải ai lxml cần. Đã kết thúc bỏ qua vấn đề này.

  1. lưu ý nơi các gói trang web của tôi đã được đặt.

  2. chuyển đến đó và grep đệ quy để nhập (kết quả cuối cùng - kết quả trùng lặp của grep phục vụ để loại bỏ các tệp riêng của lxml khỏi xem xét).

Có, không phải là câu trả lời về cách sử dụng pip để thực hiện, nhưng tôi đã không nhận được bất kỳ thành công nào từ các đề xuất tại đây vì bất kỳ lý do gì.

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

Tôi đã viết một kịch bản nhanh chóng để giải quyết vấn đề này. Kịch bản sau đây sẽ hiển thị (các) gói cha mẹ (phụ thuộc) cho bất kỳ gói nào đã cho. Bằng cách này bạn có thể chắc chắn rằng nó là an toàn để nâng cấp hoặc cài đặt bất kỳ gói cụ thể. Nó có thể được sử dụng như sau: 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))) 
Các vấn đề liên quan