我有一个在开发过程中发生变化的pip需求文件。
是否可以使pip
卸载未出现在需求文件中的软件包以及安装那些出现的软件包?有标准的方法吗?
这将允许pip需求文件成为包的规范列表 - “if if only only”方法。
更新:我建议将它作为https://github.com/pypa/pip/issues/716的新功能
简短的回答是不,你不能用pip做到这一点。
这应该卸载不在requirements.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年更新:您可能并不真的想要实际使用上述方法。 Check out pip-tools
and pip-sync
以更加强大的方式完成你可能想做的事情。
https://github.com/nvie/pip-tools
2016年5月更新:
你现在也可以使用pip uninstall -r requirements.txt
,但这完全相反 - 它卸载requirements.txt
中的所有内容
2019年5月更新:
看看pipenv。在包管理领域发生了很多事情,这使得这类问题有点过时了。
它不是pip
的特征,不是。如果你真的想要这样的东西,你可以编写一个脚本来比较pip freeze
的输出和你的requirements.txt
,但它可能比它的价值更麻烦。
使用virtualenv
,创建一个干净的环境并从requirements.txt
(重新)安装更容易,更可靠,如:
deactivate
rm -rf venv/
virtualenv venv/
source venv/bin/activate
pip install -r requirements.txt
您现在可以将-r requirements.txt
参数传递给pip uninstall
。
pip uninstall -r requirements.txt -y
至少从pip
8.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.
...
斯蒂芬的提议是一个不错的主意,但不幸的是,如果你只在文件中包含直接要求,这对你来说听起来更干净,那就不行了。
将卸载所有依赖项,甚至包括distribute
,打破pip
本身。
以下是我尝试对虚拟环境进行版本跟踪的方法。我尝试维护一个最小的requirements.txt
,包括只有直接的要求,甚至没有提到我不确定的版本限制。
但另外,我保留,并在版本跟踪(比如git)中包含我的virtualenv在venv.pip
文件中的实际状态。
这是一个示例工作流程:
使用版本跟踪设置virtualenv工作区:
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钩子自动完成,但是我们不要偏离主题。
当然,使用某些包缓存系统或pip2pi等本地存储库是有道理的
在这里抄袭@ stephen-j-fuhry是我使用的powershell等价物:
pip freeze | ? { $_ -notmatch ((gc req.txt) -join "|") }
这是一个古老的问题(但是很好的问题),事情发生了变化,因为它被问到了。
在另一个答案中有一个对pip-sync
的随意引用,但值得自己给出答案,因为它恰好解决了OP的问题。
pip-sync将requirements.txt
文件作为输入,并“正确”当前的Python环境,以便它与requirements.txt
中的内容完全匹配。这包括删除env中存在但requirements.txt
不存在的任何包。
示例:假设我们希望我们的env包含(仅)3个库:libA
,libB
和libC
,如下所示:
> cat requirements.txt
libA==1.0
libB==1.1
libC==1.2
但我们的env目前包含libC
和libD
:
> 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 -r requirements.txt