核心开发人员和加拿大人Mariatta在Twitter上询问了有关python -m pip的问题,以及谁向她介绍了该惯用法并要求其提供解释它的参考资料:
我以前就了解到我们应该使用‘python -m pip install……’,而不是简单地使用‘pip install ...’,但现在我不记得这条消息的 来源了。可能来自@brettsky或@zooba,你们有关于这方面的演讲或博文吗,以便我可以与别人分享?
——Mariatta (@mariatta) October 29,2019
现在我不确定是不是我告诉了Mariatta关于python -m pip的事,但很有可能是我,因为我从2016年起就一直要求让它成为PyPI上提供的关于如何安装包的说明。因此,这篇博客文章的目的是解释python -m pip是什么,以及为什么您在运行pip时应该使用它。
python -m pip是什么?
首先,python -m pip会使用您指定为python的Python解释器来执行pip。因此,/usr/bin/python3.7 -m pip表示您正在执行位于/usr/bin/python3.7的解释器的pip。如果您不熟悉这个标志以及它是如何工作的,您可以阅读有关-m的文档(它非常方便)。
为什么使用 python -m pip 而不是 pip/pip3?
所以您可能会说,“好的,但是我不能通过执行pip命令来运行pip吗?”答案是“可以,但是您对它的控制会更少”,我将用一个例子来解释我所说的“控制会更少”是什么意思。
假设我已经安装了Python的两个版本,比如Python 3.7和3.8(由于Python会预先安装在macOS和Linux上,这对人们来说是很常见的,更不用说您之前已经安装了Python 3.7,您还是会安装Python 3.8来使用它)。现在,如果您在您的终端中键入pip,那么它将为哪个Python解释器安装库呢?
在没有更多的细节的情况下,您的答案是您不知道。首先,您必须知道我的PATH设置是什么,比如/usr/bin是在/usr/local/bin之前还是之后(这些是安装Python的常见位置,通常优先安装于/usr/local/目录)。好的,只要您记得您安装Python 3.7和3.8的地方,它们是不同的目录,您就会知道哪个版本的pip在PATH上先出现。假设您都是手动安装它们的,也许您的操作系统附带了Python 3.7.3,而您又安装了Python 3.7.5。在这种情况下,Python的两个版本都安装在/usr/local/bin中。现在您能告诉我pip与哪个解释器相关联吗?
答案是您仍然不知道。除非您知道您在什么时候安装了每个版本,从而就会知道被写到/usr/local/bin/pip的最后一个pip副本是什么,否则您就不知道哪个解释器的pip将被用于执行pip命令。现在您可能会说,“我总是会安装最新的版本,这意味着Python 3.8.0是最后安装的,因为它比3.7.5更新。”好的,但是当Python 3.7.6出现时会发生什么呢?您的pip命令将会从使用Python 3.8变为使用Python 3.7。
但是当您使用python -m pip时,而python是您希望使用的特定解释器时,所有上述的模糊性都消失了。如果我使用python3.8 -m pip,那么我就知道pip将会在我的Python 3.8解释器中使用和安装(如果我使用的是python3.7,那么情况也一样)。
如果您是在Windows上运行,使用python -m pip还有一个额外的好处,那就是它可以让pip自我更新。基本上,当您执行pip install --upgrade pip时,系统会认为pip.exe正在运行,因此,Windows是不会让您覆盖pip.exe的。但是,如果您执行python -m pip install --upgrade pip,就可以避免这个问题,因为正在运行的是python.exe,不是pip.exe。
当我在一个激活的环境中时会怎样呢?
通常当我向一群人解释这一点时,不可避免地会有人说:“我一直使用虚拟环境,所以这对我不适用”。首先,总是使用虚拟环境会把工作做得很好(我将在这篇博客文章的后面讨论为什么这是一个最佳实践)!但说实话,我仍然主张使用python -m pip,即使在严格来说没有必要的情况下也是如此。
首先,如果您是在Windows上,您会想要继续使用python -m pip,以便能够在您的环境中更新pip。
其次,即使您在另一个操作系统上,我想说您也应该使用python -m pip,因为它在任何情况下都能工作。如果您碰巧忘记了激活您的环境,那它不仅能防止您犯错误,而且还意味着任何人都能在您身边学习到最佳实践。就我个人而言,我不觉得为一个您不经常执行的命令节省10次按键就可以让您从通用最佳实践中采用一个捷径变得合理。它还可以防止您意外地编写一些自动化脚本,这些脚本在您忘记激活环境时会执行错误的操作。
>>> 今日签到口令:em4q <<<
就我个人而言,我所使用的任何工具,如果它的执行依赖于它所运行的解释器,那我总是会使用-m来激活环境或不激活,以便我想要使用/影响的Python解释器更具目的性和明确性。
总是使用虚拟环境! 不要安装到您的全局解释器中!
虽然我们讨论的主题是如何避免搞混您的Python安装,但我想指出的是,当您在本地进行开发时,您绝不应该将其他东西安装到您的全局Python解释器中(容器是另一回事)!如果是Python的系统安装,那么如果您安装了一个操作系统所依赖的不兼容版本的库,就可能会导致系统崩溃。
但是,即使您安装了自己的Python副本,我仍然强烈建议在本地开发时不要直接安装到Python中。您最终会在您的项目之间混合不同的包,它们可能会相互冲突,您并不清楚您的每个项目真正依赖什么,等等。最好是使用环境来隔离您的各个项目和工具。在Python社区中有两种类型的环境:虚拟环境和conda环境。甚至还有一种以独立方式安装Python工具的方法。
如果您需要安装一个工具
要独立安装一个工具,我将会使用pipx。每个工具都会有自己的虚拟环境,这样它们就不会相互冲突。例如,如果您想单独安装Black,您就可以这样做,而不会意外地破坏您的mypy的单独安装。
如果您想为您的项目创建一个环境 (而且您没有使用conda)
当您需要为一个项目创建一个环境时,我个人总是会使用venv和虚拟环境。它包含在Python的stdlib中,所以您总是可以通过Python -m venv使用它(只要您不是在Debian/Ubuntu上,否则您可能必须安装python3-venv apt包)。一点小历史:实际上我删除了Python用于使用venv创建虚拟环境的旧的pyvenv命令,原因是您应该使用Python -m pip而不是pip;仅从该命令来看,您无法通过旧的pyvenv命令知道您正在为哪个解释器创建虚拟环境。请记住,您不必激活该虚拟环境来使用它所包含的解释器;只要您激活该环境,然后键入python,.venv/bin/python就会运行了。
现在有些人仍然更喜欢virtualenv,因为它在Python2上可用,而且还有其他一些额外的特性。就我个人而言,我不需要这些额外的功能,而且集成了venv就意味着我不需要使用pipx在每台机器上安装virtualenv。但是,如果venv不能满足您的需要,而您又需要一个虚拟环境,那么您可以看看virtualenv是否能满足您的需要。
如果您是一个conda用户
如果您是一个conda用户,那么您可以使用conda环境获得与venv提供的虚拟环境相同的效果。我不打算深入讨论您是否应该在您的情况中使用conda而不是venv,但是如果您发现自己使用conda然后知道您可以(也应该)为您的工作创建conda环境而不是将所有东西安装到您的基本环境中,并对您的项目所依赖的东西有一个清晰的理解(这也是您应该使用miniconda而不是anaconda的一个很好的理由,前者的安装大小比后者的十分之一还小)。
容器必不可少
在容器中工作是另一种选择,因为此时您可以跳过创建环境的部分,因为整个“机器”就是环境。只要您没有将容器安装到系统Python中,您就可以自由地进行全局安装,以保持容器的简单和直接。
我再重复一遍,尝试把这个要点讲清楚……
不要安装到您的全局Python解释器中!在进行本地开发时,请始终尝试使用虚拟环境!
我数不清有多少次我不得不帮助那些认为pip正在安装到一个Python解释器中,而实际上是安装到另一个Python解释器中的人。这种不可估量的次数也适用于当人们破坏了他们的系统,或者想知道为什么他们不能安装一些与他们之前为其他项目安装的其他东西相冲突的东西,等等,因为他们没有不怕麻烦地在他们的本地机器上设置一个环境。
因此,为了您和我的理智,请使用python -m pip并始终尝试使用虚拟环境。
英文原文:https://snarky.ca/why-you-should-use-python-m-pip/
译者:好酒不上头