Làm cách nào để sử dụng tệp yêu cầu pip để gỡ cài đặt cũng như cài đặt các gói?


90

Tôi có một tệp yêu cầu pip thay đổi trong quá trình phát triển.

Có thể pipđược thực hiện để gỡ cài đặt các gói không xuất hiện trong tệp yêu cầu cũng như cài đặt những gói xuất hiện không? Có một phương pháp tiêu chuẩn?

Điều này sẽ cho phép tệp yêu cầu pip trở thành danh sách chuẩn của các gói - một cách tiếp cận 'nếu và chỉ khi'.

Cập nhật : Tôi đã đề xuất nó như một tính năng mới tại https://github.com/pypa/pip/issues/716


3
Bạn có THỰC SỰ muốn pip gỡ cài đặt các gói tùy ý chỉ vì chương trình của bạn không yêu cầu chúng không? Âm thanh chỉ là một chút nguy hiểm ...
Scott Hunter

11
@ScottHunter Nếu bạn đang ở trong một virtualenv không có các gói trang web, đó là một điều hợp lý bạn nên làm.
Michael Mior

1
@ScottHunter Có nếu sử dụng môi trường được kiểm soát (ảo) mà tôi muốn chắc chắn về những gì ở đó - và đó là không có gì khác hiện diện có thể gây ra sự cố, ví dụ: phụ thuộc không mong muốn.
wodow

@MichaelMior Nếu đó là câu trả lời thì vui lòng thêm làm câu trả lời và tôi sẽ chấp nhận!
wodow

@wodow Đã xong. Lý do duy nhất tôi không đăng dưới dạng câu trả lời là vì có lẽ có một giải pháp hữu ích hơn có thể đưa bạn đến những gì bạn muốn.
Michael Mior

Câu trả lời:


16

Câu trả lời ngắn gọn là không, bạn không thể làm điều đó với pip.


32
như Stephen nói bên dưới:pip uninstall -r requirements.txt
Ommit

31
@Ommit Điều này không gỡ cài đặt các gói không xuất hiện trong tệp yêu cầu. Nó gỡ cài đặt tất cả các gói xuất hiện trong tệp.
Michael Mior

3
@Micheal Mior, à, tôi đã không chú ý đến câu hỏi ban đầu. Lỗi của tôi.
Ommit

4
Thêm một -yvào lệnh của @Ommit để tránh phải nhấn Y và nhập nhiều lần. Học hỏi từ những sai lầm của tôi.
Greg Hilston

1
Chỉ cần thêm: pip uninstall -r requirements.txtsẽ chỉ gỡ cài đặt các phiên bản trong tệp tệp tin request.txt của bạn. boto3==1.10.0Ví dụ: nếu bạn gỡ cài đặt , pip freezesẽ hiển thị boto3==1.0.1nếu bạn đã cài đặt nó (hoặc bất kỳ phiên bản cũ hơn) trước đó.
Jordan Mackie,

125

Thao tác này sẽ gỡ cài đặt bất kỳ thứ gì không có trong tệp tests.txt:

pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y

Mặc dù điều này sẽ không hoạt động đúng với các gói được cài đặt với -e, tức là từ kho lưu trữ git hoặc tương tự. Để bỏ qua những điều đó, chỉ cần lọc ra các gói bắt đầu bằng -ecờ:

pip freeze | grep -v -f requirements.txt - | grep -v '^#' | grep -v '^-e ' | xargs pip uninstall -y

Sau đó, rõ ràng:

pip install -r requirements.txt

Cập nhật cho năm 2016: Tuy nhiên, có thể bạn không thực sự muốn sử dụng cách tiếp cận trên. Kiểm tra pip-toolspip-sync hoàn thành những gì bạn có thể đang muốn làm theo cách mạnh mẽ hơn nhiều.

https://github.com/nvie/pip-tools

Cập nhật cho tháng 5 năm 2016:

Bây giờ bạn cũng có thể sử dụng pip uninstall -r requirements.txt, tuy nhiên điều này về cơ bản hoàn thành điều ngược lại - nó gỡ cài đặt mọi thứ trongrequirements.txt

Cập nhật cho tháng 5 năm 2019:

Kiểm tra pipenv . Rất nhiều điều đã xảy ra trong thế giới quản lý gói khiến loại câu hỏi này trở nên lỗi thời. Tuy nhiên, tôi thực sự vẫn khá hài lòng khi sử dụng công cụ pip.


5
Thật là tốt. Đối với tôi, có vẻ như đây là một cách hay để buộc các nhà phát triển phải rõ ràng về sự phụ thuộc của họ bằng cách phá vỡ mọi thứ nếu họ cài đặt thứ gì đó trên một máy chủ theo cách thủ công mà không cập nhật request.txt của họ. Tôi muốn biết loại phản hồi mà một yêu cầu kéo thêm chức năng đó sẽ tạo ra.
Stephen Fuhry

Đây là câu trả lời chính xác! Tôi đặt này trong tôi project.configtập cho Django trên Elastic Beanstalk: 05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y". Bây giờ tôi có thể khôi phục các gói pip mà không cần xây dựng lại môi trường của mình chỉ bằng cách sử dụng các nhận xét trong requirements.txt. Điều này giúp tôi tiết kiệm thời gian chết thực sự. Cảm ơn bạn!
e.thompsy

Có bao giờ đầu ra của việc đóng băng pip bắt đầu bằng # không? Nói cách khác, grep thứ hai có cần thiết không?
xor

1
Không chắc liệu có pip freezeđưa ra nhận xét hay không, nhưng một ngày nào đó họ có thể thêm nó vào API và nếu có, nó sẽ hợp lệ. Nếu họ không, thì phần trên là không nên. Dấu gạch ngang cho phép bạn sử dụng stdin từ lệnh trước đó, trong trường hợp này, dấu gạch ngang báo cho grep so sánh nội dung của pip freezepip freeze
request.txt

1
Tôi rất khuyến khích các công cụ pip. +1
ron rothman

16

Nó không phải là một tính năng của pip, không. Nếu bạn thực sự muốn một thứ như vậy, bạn có thể viết một kịch bản để so sánh đầu ra của pip freezevới của bạn requirements.txt, nhưng nó có thể sẽ phức tạp hơn giá trị của nó.

Sử dụng virtualenv, sẽ dễ dàng hơn và đáng tin cậy hơn khi chỉ cần tạo một môi trường sạch và (lại) cài đặt từ requirements.txt, như:

deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt

6
Có thể hữu ích khi chỉ gỡ cài đặt các gói không có trong tệp yêu cầu nếu một số gói (PIL, lxml, v.v.) yêu cầu biên dịch dài - đặc biệt nếu điều này diễn ra trên một máy chủ trực tiếp đang sử dụng môi trường ảo.
melinath 24/12/12

@melinath Nếu chúng không có trong tệp yêu cầu của bạn và chúng đã được cài đặt, thì quá trình biên dịch sẽ không bao giờ xảy ra nữa.
Michael Mior

1
@MichaelMior - trừ khi bạn định xóa toàn bộ virtualenv, như câu trả lời này gợi ý.
melinath

1
@melinath Nhưng nếu bạn xóa virtualenv và gói không cần thiết (và không phải trong của bạn requirements.txt), tại sao nó sẽ được cài đặt lại?
Michael Mior

3
@MichaelMior Tôi sẽ cố gắng nêu nhận xét ban đầu của mình một cách rõ ràng hơn. Có vẻ như bạn đã hiểu sai ý tôi. Hãy tưởng tượng một tệp yêu cầu đơn giản chứa PIL và lxml. Nhưng sau đó bạn quyết định không cần lxml nữa và bạn xóa nó khỏi tệp yêu cầu. Nếu bạn làm như câu trả lời này gợi ý và xóa sạch virtualenv, thì bạn phải cài đặt lại (và biên dịch lại) PIL. Sẽ hiệu quả hơn nếu có tùy chọn chỉ cần gỡ cài đặt lxml (tức là tất cả các gói không có trong tệp yêu cầu.)
melinath

11

Bây giờ bạn có thể chuyển -r requirements.txtđối số tới pip uninstall.

pip uninstall -r requirements.txt -y

Ít nhất kể từ pip8.1.2, pip help uninstallcho thấy:

...
Uninstall Options:
  -r, --requirement <file>    Uninstall all the packages listed in the given requirements file.  This option can be
                              used multiple times.
...

3
Thao tác này không gỡ cài đặt các gói không xuất hiện trong tệp. Tháo gỡ các gói mà làm xuất hiện trong tập tin.
Michael Mior

4

Đây là một câu hỏi cũ (nhưng là một câu hỏi hay), và mọi thứ đã thay đổi đáng kể kể từ khi nó được hỏi.

Có một tham chiếu trực tiếp đến pip-synctrong một câu trả lời khác, nhưng xứng đáng với câu trả lời của riêng nó, bởi vì nó giải quyết chính xác vấn đề của OP.

pip-sync lấy một requirements.txttệp làm đầu vào và "sắp xếp" môi trường Python hiện tại của bạn để nó khớp chính xác với những gì trong đó requirements.txt. Điều này bao gồm việc loại bỏ bất kỳ gói nào có trong env của bạn nhưng không có requirements.txt.

Ví dụ: Giả sử chúng ta muốn env của chúng tôi để chứa (chỉ) 3 thư viện: libA, libB, và libC, như vậy:

> cat requirements.txt
libA==1.0
libB==1.1
libC==1.2

Nhưng env của chúng tôi hiện chứa libClibD:

> pip freeze
libC==1.2
libD==1.3

Chạy pip-sync sẽ dẫn đến điều này, đây là trạng thái cuối cùng mong muốn của chúng tôi:

> pip-sync requirements.txt
> pip freeze
libA==1.0
libB==1.1
libC==1.2

Hãy cẩn thận, nếu bạn có một công cụ pip được cài đặt toàn cầu, nó sẽ không gỡ cài đặt trong virtualenv hiện đang được kích hoạt của bạn ... vẫn còn lạ, nhưng nếu không là công cụ quản lý yêu cầu thẳng thắn nhất mà tôi biết.
benzkji

3

Đề xuất của Stephen là một ý tưởng hay, nhưng tiếc là nó không hiệu quả nếu bạn chỉ đưa các yêu cầu trực tiếp vào hồ sơ của mình, điều này nghe có vẻ rõ ràng hơn đối với tôi.

Tất cả các phần phụ thuộc sẽ được gỡ cài đặt, bao gồm cả chính nó distribute, chia nhỏ pip.

Duy trì tệp yêu cầu sạch trong khi phiên bản theo dõi môi trường ảo

Đây là cách tôi cố gắng theo dõi phiên bản môi trường ảo của mình. Tôi cố gắng duy trì mức tối thiểu requirements.txt, chỉ bao gồm các yêu cầu trực tiếp và thậm chí không đề cập đến các ràng buộc phiên bản mà tôi không chắc chắn.

Nhưng bên cạnh đó, tôi giữ và bao gồm theo dõi phiên bản (giả sử như git), trạng thái thực tế của virtualenv của tôi trong một venv.piptệp.

Đây là quy trình làm việc mẫu:


thiết lập không gian làm việc virtualenv, với theo dõi phiên bản:

mkdir /tmp/pip_uninstalling
cd /tmp/pip_uninstalling
virtualenv venv
. venv/bin/activate

khởi tạo hệ thống theo dõi phiên bản:

git init
echo venv > .gitignore
pip freeze > venv.pip
git add .gitignore venv.pip
git commit -m "Python project with venv"

cài đặt một gói với các phụ thuộc, bao gồm nó trong tệp yêu cầu:

echo flask > requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

Bây giờ hãy bắt đầu xây dựng ứng dụng của bạn, sau đó cam kết và bắt đầu một nhánh mới:

vim myapp.py
git commit -am "Simple flask application"
git checkout -b "experiments"

cài đặt một gói bổ sung:

echo flask-script >> requirements.txt
pip install -r requirements.txt
pip freeze > venv.pip

... chơi với nó, rồi quay lại phiên bản trước đó

vim manage.py
git commit -am "Playing with flask-script"
git checkout master

Bây giờ gỡ cài đặt các gói không liên quan:

pip freeze | grep -v -f venv.pip | xargs pip uninstall -y

Tôi cho rằng quá trình này có thể được tự động hóa với git hook, nhưng chúng ta đừng đi lạc đề.

Tất nhiên, sẽ hợp lý khi sử dụng một số hệ thống bộ nhớ đệm gói hoặc kho lưu trữ cục bộ như pip2pi


2

Piggybacking off @ stephen-j-fuhry đây là phần mềm tương đương với powershell mà tôi sử dụng:

pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }

0

Mặc dù điều này không trực tiếp trả lời câu hỏi, nhưng một giải pháp thay thế tốt hơn requirements.txtbây giờ là sử dụng a Pipfile. Chức năng này tương tự như Ruby Gemfile. Hiện tại, bạn cần sử dụng pipenvcông cụ này nhưng hy vọng điều này cuối cùng sẽ được đưa vào pip. Điều này cung cấp pipenv cleanlệnh thực hiện những gì bạn muốn.

(Lưu ý rằng bạn có thể nhập hiện có requirements.txtvới pipenv install -r requirements.txt. Sau đó, bạn sẽ cóPipfilerequirements.txtcó thể xóa.)


-3

Bây giờ có thể sử dụng:

pip uninstall -r requirements.txt

2
Thao tác này không gỡ cài đặt các gói không xuất hiện trong tệp yêu cầu. Tháo gỡ tất cả các gói mà làm xuất hiện trong tập tin.
Michael Mior
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.