![](/img/trans.png)
[英]Why is this command need to for PIP "py -m pip install <package-name>
[英]Difference between 'python -m pip install <package-name>' and 'pip install <package-name>'
我遇到了一个问题,我试图在虚拟环境中运行 Django 应用程序,但它一直向我显示有关缺少需要安装的软件包的错误,尽管我之前确实使用pip install <package-name>
安装了它们。
在我使用python -m pip install <package-name>
安装丢失的包之前,这些问题无法解决。
我的问题是这两个命令有什么区别? 其中一个命令是否将软件包安装到虚拟环境,另一个是全局安装? 我糊涂了。
旁注:此外,运行pip freeze
显示的已安装包与运行python -m pip freeze
时显示的包不同。
更新 1:
运行pip list -v
显示使用pip install <package-name>
位于lib/python3.8/site-packages
目录下的虚拟环境文件夹中,而运行python -m pip list -v
显示包使用python -m pip <package-name>
文件位于/usr/lib/<python3 or python3.8>/<site-packages or dist-packages>
目录下。
更新 2:
我使用运行 Ubuntu 20.04 64 位的 VPS 体验了上述所有内容。 奇怪的是,当我在运行 Linux Mint 的本地机器上时,执行这两个命令的作用完全相同, pip install <package-name>
和python -m pip install <package-name>
之间没有区别python -m pip install <package-name>
在我的本地机器上。
更新 3:
我所做的是删除了我的虚拟环境并在同一目录中创建了一个具有相同名称的新环境。 为了使事情更清楚,以下屏幕截图展示了我面临的问题:
1- 下面的截图显示了pip list -v
全局运行时的结果:
2- 下面的屏幕截图显示了python -m pip list -v
在全局运行时的结果:
上面 2 个屏幕截图显示了相同的结果(两个命令都是全局执行的,没有活动的虚拟环境)。
3- 下面的屏幕截图显示了我在虚拟环境中运行pip list -v
的结果:
4- 下面的屏幕截图显示了在我的虚拟环境中运行python -m pip list -v
的结果:
以上 2 个屏幕截图显示了不同的结果(两个命令都是在激活虚拟环境时执行的)。
尽管我创建了一个新的虚拟环境,但问题仍然存在。
通常没有区别。
python -m
标志允许您运行特定模块。 例如,您可以运行python -m http.server
在当前目录中启动一个简单的服务器。
Python 包含一个“脚本”目录。 根据您的系统设置, scripts
目录中的模块可以直接从 shell 运行,无需python -m
前缀。 例如,通常您直接从 shell 运行black
。
但是,您可能不想信任直接从 shell 运行 python 模块的原因有多种,包括:
py -3.6 -m pip install something
来指定一个python版本 在 virtualenv 中,这两个命令通常会做同样的事情,因为virtualenv
会正确设置你的 PATH
欢迎来到符号链接、使用PATH
二进制可发现性和 shebang #!/...
(*nix) 的世界。
在深入了解这一切之前,让我们先谈谈pip
是什么:
pip
既是一个 python 模块(即python -m pip
( -m
表示模块))又是一个二进制$ pip
。 pip
作为二进制文件(程序)是可选的,它不是必需的。 pip
作为模块(在安装了所有 python 模块的site-packages
内)是绝对需要的! 没有它什么都不会工作,或者更糟糕的是,你会使用你安装的另一个python版本的pip
模块,然后你真的会用头撞墙......
echo $PATH
(*nix) 将显示如下内容:
$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin
这意味着系统将通过终端首先在/usr/local/bin
查找二进制文件,然后在/usr/bin
查找......等等。 如果它一开始就找到了它,那就太好了,它完成了,无需继续寻找。 您可以在不同的目录中使用相同的二进制名称, PATH
的顺序很重要,第二个永远不会被执行,永远。
我为什么要提到这个? 好吧,假设您安装了多个版本的python
或pip
,并且将其安装在错误的位置? 顺序错在哪里? 那个二进制文件不会按预期运行。
您可以拥有不同版本的pip
和python
它们彼此独立,这意味着仅仅因为您使用的是 3.8 版的python
,并不意味着您的pip
指向相同的 python 二进制文件。
检查的快速方法是:(这适用于pip
)
$ ls -ls $(which python)
0 lrwxr-xr-x 1 root wheel 75 Jan 1 2020 /usr/bin/python -> ../../System/Library/Frameworks/Python.framework/Versions/2.7/bin/python2.7
您可以看到它正在使用python
的系统版本,如果我只运行python
,我将忽略我拥有的任何其他版本,我可以通过指定版本号(例如python3.8
...
您可以通过首先弄清楚您可以使用哪些二进制文件来解决这个问题:
$ echo $PATH | sed 's/:/ /g' | xargs -n1 -I{} find {} -name 'python*' | grep -v 'config$'
/usr/local/bin/python3
/usr/local/bin/python3.9
/usr/local/bin/python3.8
/usr/bin/python3
/usr/bin/python
/usr/bin/python2
/usr/bin/pythonw
/usr/bin/pythonw2.7
/usr/bin/python2.7
假设我希望我的默认python
是python3.8
,然后执行:
$ ln -s /usr/local/bin/python3.8 /usr/local/bin/python
$ hash -r
hash -r
告诉终端忘记它之前找到的所有banaries,否则你的新符号链接将不起作用
聪明的你可能会问,如果默认的python
是在/usr/bin/python
为什么不直接使用覆盖它呢?
$ ln -sf /usr/local/bin/python3.8 /usr/bin/python
/usr/bin/
是受保护的,并且乱用系统首选项是不好的形式。 最好不要碰它, /usr/local/bin
是你(机器的用户)可以乱动的。
#!/...
在大多数情况下,您会发现pip
二进制文件(顺便说一下,这只是纯文本)以这样的方式开始:
#!/usr/bin/env python
或者
#!/usr/local/bin/python3.9
这表示,我是一个需要使用以下可执行文件运行的文本文件。 在第一个示例中,它使用系统来确定二进制python
的方式与您在终端中找到它的方式相同,请参阅上面的PATH
变量。 第二个示例是系统要使用的二进制文件的直接路径。
记住pip
是一个模块,二进制pip
字面意思是这样的:(这是稍微修改以使其尽可能基本并说明一点)
#!/usr/bin/env python
import sys
from pip._internal.cli.main import main
sys.exit(main())
python
二进制文件sys
模块...pip
模块导入main
函数main
,它返回的任何代码都将它传递给sys.exit(..)
通常会返回0
但这里或那里都更近了..仅供参考当您需要定义需要将软件包安装到哪个 python 版本时,它非常方便(对不起,我的英语不好)。 比如说,你有 python3.8 和 python3.10。 你可以做python3.8 -m pip install django
和python3.10 -m pip install django
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.