如何使用 pip 需求文件卸载和安装软件包?

我有一个 pip 需求文件,在开发过程中发生变化。

pip是否可以做到 卸载软件包不出现在需求文件,以及安装那些出现?有标准的方法吗?

这将允许 pip 需求文件成为包的规范列表——一种“如果且仅当”的方法。

更新 : 我在 < a href = “ https://github.com/pypa/pip/issues/716”> https://github.com/pypa/pip/issues/716中建议将其作为一个新特性

101903 次浏览

这不是 pip的特色。如果您真的想要这样一个东西,您可以编写一个脚本来比较 pip freezerequirements.txt的输出,但是这可能比它的价值更麻烦。

使用 virtualenv,只需创建一个干净的环境并(重新)从 requirements.txt安装,比如:

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

简短的回答是不行,你不能这么对 Pip。

这应该会卸载任何不在 Requments.txt 中的内容:

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

尽管这对于安装了 -e的包(例如来自 git 存储库或类似的包)来说并不能很好地工作。要跳过这些步骤,只需过滤掉从 -e标志开始的软件包:

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

那么,很明显:

pip install -r requirements.txt

2016年最新情况: 不过,实际上您可能并不想使用上述方法。看看 ABC0和 pip-sync可以以一种更加健壮的方式完成您可能想要完成的任务。

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

2016年5月更新:

您现在也可以使用 pip uninstall -r requirements.txt,但是这基本上完成了相反的工作-它卸载了 requirements.txt中的所有内容

2019年5月更新:

检查 Pipenv诗歌。在包管理的世界中已经发生了很多事情,这使得这种问题有点过时。其实我还是很喜欢使用微型工具的。

Piggybackoff@stephen-j-fuhry 在这里是我使用的 Powershell 等价物:

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

斯蒂芬的提议是个不错的主意,但不幸的是它行不通 如果您只在文件中包含直接要求,这听起来 对我来说更干净。

将卸载所有依赖项, 甚至包括 distribute,分解 pip本身。

在跟踪虚拟环境的版本时维护一个干净的需求文件

下面是我尝试对我的虚拟环境进行版本跟踪的方法。 我尽量保持最小的 requirements.txt,包括只 直接的需求,甚至没有提到版本约束在哪里 我不确定。

但是除此之外,我保留并包含在版本跟踪中(比如 git) , 在 venv.pip文件中我的 viralenv 的实际状态。

下面是一个示例工作流程:


设置 viralenv 工作区,带版本跟踪:

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

初始化版本追踪系统:

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

安装具有依赖关系的包,并将其包含在需求文件中:

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

现在开始构建你的应用程序,然后提交并开始一个新的分支:

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

安装一个额外的软件包:

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

... 玩一玩,然后回到早期版本

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

现在卸载无关的软件包:

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

我认为这个过程可以通过 git 钩子来自动化,但是我们不要偏离主题。

当然,使用一些包缓存系统是有意义的 或者像 < a href = “ https://github.com/woever/pip2pi”rel = “ nofollow”> pip2pi 这样的本地存储库

现在可以使用:

pip uninstall -r requirements.txt

现在可以将 -r requirements.txt参数传递给 pip uninstall

pip uninstall -r requirements.txt -y

至少在 pip8.1.2中,pip help uninstall显示:

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

虽然这不能直接回答这个问题,但是现在更好的 requirements.txt替代品是使用 Pipfile。这个函数类似于 RubyGemfile。目前,您需要使用 pipenv工具,但是希望这最终将被并入到 pip中。这提供了 pipenv clean命令,可以执行您想要的操作。

(注意,可以用 pipenv install -r requirements.txt导入现有的 requirements.txt。在此之后,你应该有一个 Pipfilerequirements.txt可以删除。)

这是一个古老的问题(但是一个好的问题) ,自从它被提出以来,事情已经发生了很大的变化。

在另一个答案中有一个对 pip-sync的随手引用,但是它应该有自己的答案,因为它恰好解决了 OP 的问题。

Pip-sync 接受一个 requirements.txt文件作为输入,并“真实”当前的 Python 环境,使其与 没错匹配。这包括 移除的任何包,目前在您的环境,但没有从 requirements.txt

示例: 假设我们希望 env 包含(仅)3个库: libAlibBlibC,如下所示:

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

但我们的环境目前包含 libClibD:

> pip freeze
libC==1.2
libD==1.3

运行 pip-sync 将导致以下结果,这是我们所期望的最终状态:

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

这里有一个简单有效的解决方案:

pip uninstall $(pip freeze) -y

您可以创建一个包含所有已安装包的新文件

pip freeze > uninstall.txt

然后卸载所有这些

pip uninstall -r uninstall.txt -y

然后最后重新安装您在原始 Requments.txt 文件中的包

pip install -r requirements.txt