Kou*_*nda 14 python pip python-3.x
-m python -m pip install <package>是什么意思?或使用升级点子时python -m pip install --upgrade pip。
Tim*_*sen 129
考虑以下场景。
您安装了三个版本的 Python:
您的“默认”版本是 3.8。它是第一个出现在你的路径中的。因此,当您在 shell 中键入python3(Linux 或 Mac)或(Windows)时,您将启动 3.8 解释器,因为这是遍历您的路径时找到的第一个 Python 可执行文件。python
假设您正在启动一个想要使用 Python 3.9 的新项目。您创建一个名为的虚拟环境.venv并激活它。
python3.9 -m venv .venv # "py -3.9" on Windows
Run Code Online (Sandbox Code Playgroud)
source .venv/bin/activate # ".venv\Scripts\activate" on Windows
Run Code Online (Sandbox Code Playgroud)
我们现在已经使用 Python 3.9 激活了虚拟环境。python在 shell 中键入会启动 3.9 解释器。
但是,如果你输入
pip install <some-package>
Run Code Online (Sandbox Code Playgroud)
那么使用的是什么版本pip呢?是默认版本(即Python 3.8)的pip,还是虚拟环境中的Python版本?
解决这种歧义的一个简单方法就是使用
python -m pip install <some-package>
Run Code Online (Sandbox Code Playgroud)
该-m标志确保您使用的 pip 与活动的 Python 可执行文件绑定。
始终使用 是一种很好的做法-m,即使您只安装了一个用于创建虚拟环境的 Python 全局版本。
所谓的路径是系统搜索可执行文件的目录列表。当您键入命令(例如 )时python,将从第一个目录遍历到最后一个目录,搜索与您键入的命令匹配的文件名。
如果找到文件名/命令,则执行匹配的文件,而不考虑以后可能的匹配。如果没有匹配,您将得到一个Command not found或其变体。此行为是设计使然。
在 UNIX 系统上,路径环境变量称为$PATH,而在 Windows 系统上,它称为%PATH%
-m(2022 年 12 月)大多数查看此内容的人可能会想要上面用 pip 给出的解释。但从更一般的意义上来说,当使用 时python -m some_module,该-m标志使 Pythonsome_module作为脚本执行。文档中对此进行了说明,但如果没有一些基础知识,可能很难理解。
“作为脚本运行”是什么意思?
在 Python 中,模块some_module通常通过import some_module导入文件顶部的语句导入到另一个 Python 文件中。这使得可以使用some_module导入文件中定义的函数、类和变量。some_module要作为脚本执行而不是导入它,您可以if __name__ == "__main__"在文件内定义一个块。python some_module.py在命令行上运行时会执行此块。这很有用,因为您不希望此代码块在导入其他文件时运行,但您确实希望它在从命令行调用时运行。
对于项目内的模块,此脚本/模块构造应按原样运行,因为从终端运行时,Python 会从工作目录中查找模块:
python some_module.py
Run Code Online (Sandbox Code Playgroud)
但对于属于 Python 标准库一部分的模块,这将不起作用。Python 文档中的示例使用timeit(pip工作原理相同):
python3 timeit -s 'print("hello")' # 'python timeit.py ...' fails as well
Run Code Online (Sandbox Code Playgroud)
这会返回错误:"python: can't open file '/home/<username>/timeit': [Errno 2] No such file or directory"
添加该-m标志告诉 Python 在路径中查找timeit.py并执行if __name__ == "__main__"文件中的子句。
python3 -m timeit -s 'print("hello")'
Run Code Online (Sandbox Code Playgroud)
这按预期工作。
timeit 模块的块源可以在此处if __name__ == "__main__"找到。
nav*_*rri 12
参数是模块名称,您不能给文件扩展名(.py)。module-name应该是一个有效的Python模块名称,但是实现可能并不总是强制执行此操作(例如,它可能允许您使用包含连字符的名称)。
包名称也是允许的。当提供软件包名称而不是常规模块时,解释器将执行。main作为主要模块。这种行为故意类似于处理作为脚本参数传递给解释器的目录和zipfile。
小智 10
当-m与python命令行上的语句一起使用时,后跟一个<module_name>,则它使模块能够作为可执行文件执行。
你可以参考 python 文档,或者运行 python --help
如果您输入 python --help
你得到
// More flags above
-m mod : run library module as a script (terminates option list)
// and more flags below
Run Code Online (Sandbox Code Playgroud)
如果您使用command --help或,终端中的许多内容将向您展示如何使用它man command
这实际上是一个有趣的问题,所以让我们探索一下由@jedwards 在顶部评论中链接的 pep 338 。
-m 标志最初有一个更简单的目的 - 将模块名称转换为脚本名称。在 python 2.4 中,行为是:
the command line is effectively reinterpreted from python <options> -m
<module> <args> to python <options> <filename> <args>.
Run Code Online (Sandbox Code Playgroud)
这看起来不太有用,但当时就是这么做的。Pep 338 进一步扩展了这种行为。
提出的语义相当简单[原文如此]:如果 -m 用于执行模块,则 PEP 302 导入机制用于在根据顶级语义执行模块之前定位该模块并检索其编译的代码模块。
它还进一步解释说,python 将识别模块所在的包,使用标准流程导入该包,然后运行该模块。据我了解,调用“python3 -m package.module”与调用相同:
python3
from package import module
Run Code Online (Sandbox Code Playgroud)
-m 标志将运行模块作为__file__而不是__main__。它还会将本地目录插入 sys.path 而不是脚本的目录。因此,它破坏了相对导入,尽管这不是故意的,因此作者建议始终使用绝对导入。它还取决于你如何称呼它 - “python3 -m package.module”与“python3 -m module”不同。
理论上它很简单——它加载 python 并导入模块,而不是将代码转储到__main__. 在实践中,这会产生很多影响。这是一个不同的导入系统,其行为也不同。其中一些更改并非有意为之,而是在实施后才发现。Python 的导入很混乱,混淆也没关系。
令人惊讶的是,当有些人说这个问题太简单而无需费心时,这个问题却很难回答。
据我所知,实际目的是当您不在目录中时,您可以使用点表示法来运行脚本。
你可以运行
python -m path.to.my.happy.place
而不是进入path/to/my/happy并运行python place.py
| 归档时间: |
|
| 查看次数: |
10027 次 |
| 最近记录: |