使用`python -m pip'而不是只是`pip'有什么影响?

发布于 2025-01-26 04:10:33 字数 234 浏览 1 评论 0 原文

当我使用 python -m pip install< package> 时,这与仅使用 pip install< package> 有何不同?同样,为什么我要编写 python -m pip install -upgrade pip 升级pip,而不是 pip install -upgrade -upgrade pip

When I use python -m pip install <package>, how is that different from using just pip install <package>? Similarly, why would I write python -m pip install --upgrade pip to upgrade Pip, instead of just pip install --upgrade pip?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(8

城歌 2025-02-02 04:10:33

考虑以下情况。

您安装了三个版本的Python:

  • Python 3.7
  • Python 3.8
  • Python 3.9

您的“默认”版本为3.8。这是出现在您的路径中的第一个。因此,当您键入 python3 (linux或mac)或 python (windows)在shell中,您将启动3.8解释器,因为这是第一个在穿越时发现的python可执行文件你的道路。

假设您正在启动一个新项目,您要在其中使用Python 3.9。您创建一个称为 .venv 的虚拟环境并激活它。

python3.9 -m venv .venv         # "py -3.9" on Windows
source .venv/bin/activate    # ".venv\Scripts\activate" on Windows 

现在,我们使用Python 3.9激活了虚拟环境。在外壳中键入 python 启动了3.9解释器。

但是,如果您键入

pip install <some-package>

,则使用哪种版本的 pip ?是默认版本的PIP,即Python 3.8还是虚拟环境中的Python版本?

解决这种歧义的一种简单方法是仅使用

python -m pip install <some-package>

-M 标志,确保您使用与活动python可执行的pip。

即使您只安装了一个全局版本的Python,也可以始终使用 -M ,这是一个很好的做法。

关于。路径

所谓的路径是您的系统搜索可执行文件的目录列表。当您键入命令(例如 python )时,此列表将从第一个目录到最后一个目录,搜索与您键入的命令匹配的文件名。

如果找到文件名/命令,则匹配的文件将执行,而无需考虑潜在的以后匹配。如果没有发生匹配,则找不到命令或其变体。这种行为是设计的。

在UNIX系统上,路径环境变量被称为 $ path ,而在Windows系统上,它被称为%path%

更多有关 -m -flag(2022年12月)

大多数查看此问题的人可能希望上面用PIP给出的解释。不过,从更一般的意义上讲,当使用 python -m some_module 时, -m flag使Python Execute some_module 作为脚本。这在
“以脚本运行”是什么意思

?在导入文件的顶部语句。这可以使用 some_module 在导入文件中定义的函数,类和变量。
要执行 some_module 作为脚本而不是导入它,如果__name__ ==“ __ -main __” block在文件中,您将定义。在命令行上运行 python some_module.py 时,该块将执行。这很有用,因为您 不希望此代码块在导入其他文件时运行,但是您 do 希望它在从命令行调用时运行。

对于项目中的模块,此脚本/模块构造应按原样运行,因为从终端运行时,Python会从您的工作目录中找到模块:

python some_module.py

但是对于Python标准库的一个模块,这将行不通。 Python文档中的示例使用 timeIt pip 工作相同):

python3 timeit -s 'print("hello")'  # 'python timeit.py ...' fails as well 

这返回错误:“ Python:coble file'/home/&lt ;用户名&gt;/timeit':[errno 2]否此类文件或目录“

添加 -m flag告诉Python告诉Python,请在 timeit.py.py 的路径中寻找路径并执行如果__name__ ==“ __ -main __” 从文件中的子句。

python3 -m timeit -s 'print("hello")'

这是预期的。

的来源如果__name __ ==“ __ main __” 可以找到时间级模块的块此处

Consider the following scenario.

You have three versions of Python installed:

  • Python 3.7
  • Python 3.8
  • Python 3.9

Your "default" version is 3.8. It's the first one appearing in your path. Therefore, when you type python3 (Linux or Mac) or python (Windows) in a shell you will start a 3.8 interpreter because that's the first Python executable that is found when traversing your path.

Suppose you are then starting a new project where you want to use Python 3.9. You create a virtual environment called .venv and activate it.

python3.9 -m venv .venv         # "py -3.9" on Windows
source .venv/bin/activate    # ".venv\Scripts\activate" on Windows 

We now have the virtual environment activated using Python 3.9. Typing python in a shell starts the 3.9 interpreter.

BUT, if you type

pip install <some-package>

Then what version of pip is used? Is it the pip for the default version, i.e. Python 3.8, or the Python version within the virtual environment?

An easy way to get around that ambiguity is simply to use

python -m pip install <some-package>

The -m flag makes sure that you are using the pip that's tied to the active Python executable.

It's good practice to always use -m, even if you have just one global version of Python installed from which you create virtual environments.

Re. path

The so-called path is a list of directories where your system searches for executables. When you type a command, like python, this list is traversed from the first directory to the last, searching for a filename that matches the command you typed.

If the filename/command is found, the matched file gets executed without taking into account potential later matches. If no match occurs, you get a Command not found or a variation thereof. This behavior is by design.

On UNIX systems the path environment variable is called $PATH, while on Windows systems it's referred to as %PATH%

More general comments about the -m-flag (Dec. 2022)

Most people viewing this will likely want the explanation given above with pip. In a more general sense though, when using python -m some_module, the -m flag makes Python execute some_module as a script. This is stated in the docs, but might be difficult to understand without some baseline knowledge.
What does it mean to "run as a script"?

In Python, a module some_module is typically imported into another Python file with an import some_module statement at the top of the importing file. This enables the use of functions, classes, and variables defined in some_module inside the importing file.
To execute some_module as a script instead of importing it, you would define an if __name__ == "__main__" block inside the file. This block gets executed when running python some_module.py on the command line. This is useful because you do not want this code block to run when importing into other files, but you do want it to run when invoked from the command line.

For modules inside your project, this script/module construct should run as is, because Python will find the module from your working directory when running from the terminal:

python some_module.py

But for modules that are part of Python's Standard Library, this will not work. The example from the Python docs uses timeit (pip works the same):

python3 timeit -s 'print("hello")'  # 'python timeit.py ...' fails as well 

This returns the error: "python: can't open file '/home/<username>/timeit': [Errno 2] No such file or directory"

Adding the -m flag tells Python to look in path for timeit.py and execute the if __name__ == "__main__" clause from the file.

python3 -m timeit -s 'print("hello")'

This works as expected.

The source for the if __name__ == "__main__" block for the timeit module can be found here.

说好的呢 2025-02-02 04:10:33

来自 python docs

由于参数是一个模块名称,因此您不得给出文件扩展名(.py)。 模块名称应该是有效的Python模块名称,但是实现可能并不总是执行此功能(例如,它可以允许您使用包含连字符的名称)。

包装名称也允许。当提供软件包名称而不是普通模块时,解释器将执行&lt; pkg&gt; .__主__ 作为主模块。这种行为故意类似于将目录和邮政编码作为脚本参数传递给解释器的目录和邮政编码。

From Python Docs:

Since the argument is a module name, you must not give a file extension (.py). The module-name should be a valid Python module name, but the implementation may not always enforce this (e.g. it may allow you to use a name that includes a hyphen).

Package names are also permitted. When a package name is supplied instead of a normal module, the interpreter will execute <pkg>.__main__ as the main module. This behaviour is deliberately similar to the handling of directories and zipfiles that are passed to the interpreter as the script argument.

拥有 2025-02-02 04:10:33

键入 python - -help

如果您

// More flags above
-m mod : run library module as a script (terminates option list)
// and more flags below

如果您使用命令-help man命令

If you type python --help

You get

// More flags above
-m mod : run library module as a script (terminates option list)
// and more flags below

A great many things in a terminal will show you how to use it if you either use command --help or man command

伤感在游骋 2025-02-02 04:10:33

-m 代表模块名称

来自命令行和环境

python [-bbdehiioqssuvvwx?] [-c命令| -M模块名称|脚本| - ] [args]

The -m stands for module-name.

From Command line and environment:

python [-bBdEhiIOqsSuvVWx?] [-c command | -m module-name | script | - ] [args]

ペ泪落弦音 2025-02-02 04:10:33

-m 与命令行上的 python 语句一起使用时,然后是&lt; module_name&gt; ,然后使模块成为作为可执行文件执行。

您可以参考相同的python文档,也可以运行 python -help

When -m is used with a python statement on the command line, followed by a <module_name>, then it enables the module to be executed as an executable file.

You can refer to python docs for the same, or run python --help

随风而去 2025-02-02 04:10:33

这实际上是一个有趣的问题,所以让我们探索@jedwards链接的Pep 338,

-m标志最初提供了更简单的目的 - 将模块名称转换为脚本名称。在Python 2.4中,行为是:

the command line is effectively reinterpreted from python <options> -m
<module> <args> to python <options> <filename> <args>.

这似乎不是很有用,但这就是当时所做的。 PEP 338进一步扩展了这一行为。

提出的语义非常简单[sic]:如果-m用于
执行模块PEP 302导入机制用于定位
在执行模块之前,模块并检索其编译的代码
根据顶级模块的语义。

它继续解释说,Python将识别模块来自的软件包,使用标准过程导入该软件包,然后运行模块。据我了解,调用“ Python3 -M package.module”与调用相同:

python3
from package import module

-m标志将将模块运行为 __文件__ ,而不是 __ MAIN __ 。它还将将本地目录插入SYS.Path,而不是脚本的目录。因此,它破坏了相对进口,尽管这不是故意的,因此作者建议始终使用绝对进口。这也取决于您将其称为“ Python3 -m package.module”的方式不同于“ python3 -m模块”。

从理论上讲,它很简单 - 它加载了python并导入模块,而不是将代码倾倒到 __ Main __ 。。这是一个不同的导入系统,其行为不同。其中一些更改不是故意的,只有在实施后才发现。 Python的进口是一团糟,可以混淆。

This is actually an interesting question, so let's explore pep 338 linked by @jedwards in the top comment.

The -m flag originally served a simpler purpose- to convert a module name into a script name. In python 2.4, the behavior was:

the command line is effectively reinterpreted from python <options> -m
<module> <args> to python <options> <filename> <args>.

This doesn't seem very useful, but that's what it did back then. Pep 338 extends this behavior further.

The semantics proposed are fairly simple [sic]: if -m is used to
execute a module the PEP 302 import mechanisms are used to locate the
module and retrieve its compiled code, before executing the module in
accordance with the semantics for a top-level module.

It goes on to explain further that python will identify the package the module is from, import that package using the standard process, and run the module. From what I understand calling "python3 -m package.module" is the same as calling:

python3
from package import module

The -m flag will run the module as __file__ and not __main__. It will also insert the local directory into sys.path instead of the script's directory. It therefore breaks relative imports, although this was not intentional, and the authors therefore recommend to always use absolute imports. It also depends on how you call it- "python3 -m package.module" is not the same as "python3 -m module".

In theory it's simple- it loads up python and imports the module instead of dumping the code into __main__. In practice that has many effects. It's a different import system that behaves differently. Some of those changes were not intentional and were only discovered after implementation. Python's imports are a mess and it's okay to be confused.

只怪假的太真实 2025-02-02 04:10:33

当有人说这个问题太简单而无法打扰时,这很难回答。

据我所知,实际目的是这样,因此您可以在不在目录中时使用点符号来运行脚本。

你可以运行
python -m path.to.my.happy.place

而不是在路径/to/to/my/happy 和运行 python place.py

Amazing this is so hard to answer when some people say the question is too simple to bother with.

As far as I can tell, the practical purpose is so you can use dot notation to run your script when you aren't in the directory.

You can run
python -m path.to.my.happy.place

instead of being in path/to/my/happy and running python place.py

清音悠歌 2025-02-02 04:10:33

如果已安装了多个版本的Python,并且要升级PIP pip install -upgrade pip 您如何知道哪个Python版本会受到影响?它取决于壳的路径变量。在这种情况下,您可能还会受到警告。为了避免这种混乱使用 -m ,它在变量。这是 -m 的另一个优点。

# importing module
import sys
  
# printing all directories for 
# interpreter to search
sys.path

If you have multiple versions of python installed and you want to upgrade pip pip install --upgrade pip how do you know which python version will be affected? it depends on path variable for the shell. You might also get warning in this case. To avoid this confusion use -m then it looks in variable sys.path. This is another advantage of -m.

# importing module
import sys
  
# printing all directories for 
# interpreter to search
sys.path
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文