首先,让我们用“python –help”来看看它的解释:
-m mod : run library module as a script (terminates option list)
“mod”是“module”的缩写,即“-m”选项后面的内容是 module(模块),其作用是把模块当成脚本来运行。
“terminates option list”意味着“-m”之后的其它选项不起作用,在这点上它跟“-c”是一样的,都是“终极选项”。官方把它们定义为“接口选项”(Interface options),需要区别于其它的普通选项或通用选项。
“-m”发展演变
最早引入 -m 选项的是 Python 2.4 版本(2004年),当时功能还挺受限,只能作用于普通的内置模块(如 pdb 和 profile)。
随后,知名开发者 Nick Coghlan 提出的《PEP 338 — Executing modules as scripts》把它的功能提升了一个台阶。这个 PEP 在 2004 年提出,最终实现在 2006 年的 2.5 版本。
(插个题外话:Nick Coghlan 是核心开发者中的成员之一,也是第一届指导委员会的五人成员之一。记得当初看材料,他是在 2005 年被选为核心开发者的,这时间与 PEP-338 的时间紧密贴合)
2009 年,在 Python 3.1 版本中,只需给定包的名称,就能定位和运行它的“__main__”子模块。2014 年,-m 扩展到支持命名空间包。
至此,经过十年的发展演变,-m 选项变得功能齐全,羽翼丰满。
为什么使用python -m pip
胜于pip
/ pip3
?
我们可能会习惯性地使用“pip install xxx”,或者做了版本区分时用“pip3 install xxx”,总之不在前面用“python -m”做指定。但这种写法可能会出问题。
假设我安装了两个版本的Python,例如Python 2.7和3.8(由于在macOS和Linux上安装了Python,这对于人们来说是很常见的,更不用说您可能已经安装了Python 3.8并在之前安装了Python的情况下使用2.7)。现在,如果您要输入pip
终端,它将为哪个Python解释器安装?
存在多个 Python 版本的环境中,这种写法可以精确地控制第三方库的安装位置。例如用“python3.8 -m pip”,可以明确指定给 3.8 版本安装,而不会混淆成其它的版本。
“-m”方式与直接运行脚本相比,在实现上有什么不同呢?
- 直接运行脚本时,相当于给出了脚本的完整路径(不管是绝对路径还是相对路径),解释器根据文件系统的查找机制, 定位到该脚本,然后执行。
- 使用“-m”方式时,解释器需要在不 import 的情况下,在所有模块命名空间 中查找,定位到脚本的路径,然后执行。为了实现这个过程,解释器会借助两个模块:
pkgutil
和runpy
,前者用来获取所有的模块列表,后者根据模块名来定位并执行脚本。
原创文章,作者:huoxiaoqiang,如若转载,请注明出处:https://www.huoxiaoqiang.com/experience/pythone/2805.html