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


89

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

可以pip是由卸载,不会出现在需求文件以及安装那些确实出现包?有没有标准的方法?

这将使pip需求文件成为软件包的规范列表-一种“仅当且仅当”的方法。

更新:我在https://github.com/pypa/pip/issues/716上将其建议为一项新功能


3
您是否真的要pip仅仅因为您的程序不需要它们而卸载任意软件包?听起来有点危险...
Scott Hunter

11
@ScottHunter如果您在没有站点软件包的virtualenv中,这是一个合理的选择。
Michael Mior 2012年

1
@ScottHunter是的,如果使用的是受控(虚拟)环境,并且我想确定其中的某些内容,那么这里没有其他可能导致问题的内容,例如意外的依赖关系。
wodow

@MichaelMior如果这是答案,请添加为答案,我会接受!
wodow

@wodow完成。我之所以没有发布答案的唯一原因是,可能有一个更有用的解决方案可以使您找到想要的东西。
Michael Mior 2012年

Answers:


16

简短的答案是不,您无法使用pip做到这一点。


32
正如史蒂芬(Stephen)所说:pip uninstall -r requirements.txt
省略

31
@Ommit这不会卸载未出现在需求文件中的软件包。它将卸载确实出现在文件中的所有软件包。
Michael Mior

3
@Micheal Mior,啊,我对原始问题没有给予足够的重视。我的错。
省略

4
-y在@Ommit的命令中添加a以避免必须按Y并多次输入。从我的错误中学习。
格雷格·希尔斯顿

1
只是添加:pip uninstall -r requirements.txt只会卸载您的requirements.txt中的版本。boto3==1.10.0例如,如果您进行卸载,pip freeze将显示boto3==1.0.1以前是否已安装(或任何较旧的版本)。
乔丹·麦基

125

这应该卸载require.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年更新:不过, 您可能真的不想真正使用上述方法。找出pip-toolspip-sync以更强大的方式完成您可能要完成的任务。

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

2016年5月更新:

您现在也可以使用pip uninstall -r requirements.txt,但是基本上可以达到相反的效果-可以卸载requirements.txt

2019年5月更新:

检查pipenv。软件包管理领域发生了很多事情,使这种问题过时了。不过,我实际上仍然很高兴使用pip工具。


5
那样就好了。对我来说,这似乎是一种很好的方式,通过在不手动更新需求的情况下,在主机上手动安装某些东西,破坏了一切,从而破坏了开发人员的依赖关系。我很想知道添加该功能的请求请求会产生什么样的反馈。
史蒂芬·弗里

这是正确的答案!我将其project.config放在弹性Beanstalk上的Django文件中05_pip_clean: command: "pip freeze | grep -v -f requirements.txt - | grep -v '^#' | xargs pip uninstall -y"。现在,仅通过使用中的注释,就可以回滚pip包而无需重建环境requirements.txt。这为我节省了真正的停机时间。谢谢!
e.thompsy 2014年

是否有以#开头的pip冻结输出?换句话说,第二个grep是否必要?
xor 2015年

1
不确定是否pip freeze发表评论,但是有一天他们可能会将其添加到API中,如果这样做,它将是有效的。如果他们不这样做,那么以上内容就是禁止操作。破折号允许您使用上一条命令中的stdin,在这种情况下,破折号告诉grep将pip freezepip freeze
Requirements.txt

1
我强烈推荐点子工具。+1
罗恩·罗斯曼

16

这不是的功能pip,不。如果您确实想要这样的东西,则可以编写脚本以将的输出pip freeze与您的进行比较requirements.txt,但这可能会比其价值更大。

使用virtualenv,只需创建一个干净的环境并从重新安装即可requirements.txt,这样更容易且更可靠:

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

6
如果某些软件包(PIL,lxml等)需要冗长的编译-仅当这是在使用虚拟环境的实时服务器上进行时,仅卸载那些不在需求文件中的软件包可能会很有用。
melinath

@melinath如果它们不在您的需求文件中并且已经被安装,那么编译就不必再发生了。
Michael Mior 2014年

1
@MichaelMior-除非您要擦除整个virtualenv,如该答案所示。
melinath

1
@melinath但是,如果您擦除virtualenv并且不需要该软件包(并且不在您的包中requirements.txt),为什么还要再次安装它呢?
Michael Mior 2014年

3
@MichaelMior我将尝试更明确地陈述我的原始评论。看来您可能误解了我的意思。想象一个简单的需求文件,其中包含PIL和lxml。但是随后您决定不再需要lxml,并将其从需求文件中删除。如果按照此答案的建议进行操作并擦除virtualenv,则必须重新安装(并重新编译)PIL。选择简单地卸载lxml(即,所有未在需求文件中的软件包)的选项将更加有效
2014年

11

您现在可以将-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.
...

3
这不会卸载文件中未出现的软件包。它将卸载确实出现在文件中的软件包。
Michael Mior

4

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

pip-sync在另一个答案中有一个临时引用,但值得自己回答,因为它可以精确地解决OP的问题。

PIP同步需要一个requirements.txt文件作为输入,而“trues了”当前的Python环境,使其符合究竟是什么在这requirements.txt。这包括从中删除环境中存在但不存在的所有软件包 requirements.txt

例如:假设我们希望我们的ENV含有(只)3个库:libAlibB,和libC,就像这样:

> 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工具,它将无法在您当前激活的virtualenv中卸载...仍然很奇怪,但否则我所知道的最直接的需求管理工具。
benzkji

3

Stephen的提议是一个好主意,但是不幸的是,如果您仅在文件中包含直接要求,那么它就行不通,对我来说听起来更干净。

所有依赖项都将被卸载,包括甚至distribute崩溃pip

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

这是我尝试对虚拟环境进行版本跟踪的方法。我尝试保持最低requirements.txt要求,仅包括直接要求,甚至在不确定的地方甚至不提及版本约束。

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

这是一个示例工作流程:


设置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 hooks自动执行该过程,但让我们别无所求。

当然,然后使用某些程序包缓存系统或本地存储库(如pip2pi)才有意义


2

here带@ stephen-j-fuhry这是我使用的Powershell等效项:

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

0

虽然这不能直接回答问题,但requirements.txt现在最好的替代方法是使用Pipfile。此功能类似于Ruby Gemfile。当前,您需要使用该pipenv工具,但希望最终将其合并到中pip。这提供了pipenv clean执行所需功能的命令。

(请注意,您可以使用导入现有requirements.txtpipenv install -r requirements.txt。之后,您应该有一个Pipfilerequirements.txt可以将其删除。)


-3

现在可以使用:

pip uninstall -r requirements.txt

2
这不会卸载没有出现在需求文件中的软件包。它将卸载确实出现在文件中的所有软件包。
Michael Mior
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.