Python中m参数的作用


使用 python3 xxx.py 和 python3 -m xxx.py 有什么区别

Python中m参数的作用


  • 我们通过对应的参数解释可以得知,就是把某个 Python 模块当做脚本来运行,而为什么需要这样做呢?
➜ python --help
usage: /Users/escape/.pyenv/versions/MoviesList/bin/python [option] ... [-c cmd | -m mod | file | -] [a
Options and arguments (and corresponding environment variables):
-m mod : run library module as a script (terminates option list)
  • 常见的 Python 文件的运行方式,有如下两种方式,而他们究竟有什么区别呢?
# 直接运行
$ python3 app/test.py

# 模块运行
$ python3 -m app.test
  • 其实,核心的知识点就是:不同的加载 py 文件的方式会影响 sys.path 这个变量的值。而 sys.path 究竟有何意义呢?这里,我们可以简单理解为 Linux 操作系统中的 PATH 变量。其用于是指定当前 Python 解释器的运行环境,告诉 Python 解释器应该这那些目录下去寻找依赖的库!举个例子,来说明下面。
➜ tree .
.
└── lib
    ├── __init__.py
    └── app.py
import sys

def main():
    for line in sys.path:
        print(line)

if __name__ == '__main__':
    print(__name__)
    main()
# 直接运行
__main__
/Users/escape/Fuckcode/MoviesList/lib
/Users/escape/.pyenv/versions/3.9.0/lib/python39.zip
......
# 模块运行
➜ python -m lib.app
__main__
/Users/escape/Fuckcode/MoviesList
/Users/escape/.pyenv/versions/3.9.0/lib/python39.zip
......
  • 仔细观察输出的话,很容易发现:直接运行的方式,第一个搜索的路径是子模块目录;以模块运行的方式,第一个搜索路径是当前目录。而这样作用又有什么好处呢?好处在于,当我们运行的 Python 文件中相对引入其他模块的话,不会报错。
➜ tree .
.
├── app
│   ├── __init__.py
│   └── test.py
└── lib
    ├── __init__.py
    └── app.py

这里补充下,sys.path 变量的初始值的来源。

  • 第一次导入模块步骤:之后直接从内存加载
    • [1] 搜集并找到对应模块文件
    • [2] 在必要时把模块文件编译成字节码
    • [3] 执行模块的代码来创建所定义的对象
  • 搜索路径顺序
    • [1] 程序的主目录
    • [2] PYTHONPATH 系统变量
    • [3] 标准库目录
    • [4] .pth文件
  • 搜索文件类型
    • [1] a.py 代码源文件
    • [2] a.pyc 字节码文件
    • [3] 目录a作为包导入
    • [4] s.soa.dlla.pyd 编译扩展文件
    • [5] 用 c 编译好的内置模块
    • [6] zip 文件包
# 搜索路径都汇总在sys.path变量里面
# 可以通过对sys.path的操作达到我们需要的效果
In [1]: import sys

In [2]: sys.path
Out[2]:
['',
 '/usr/local/bin',
 '/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python36.zip',
 '/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6',
 '/usr/local/Cellar/python/3.6.4_4/Frameworks/Python.framework/Versions/3.6/lib/python3.6/lib-dynload',
 '/usr/local/lib/python3.6/site-packages',
 '/usr/local/lib/python3.6/site-packages/IPython/extensions',
 '/Users/escape/.ipython']

文章作者: Escape
版权声明: 本博客所有文章除特別声明外,均采用 CC BY 4.0 许可协议。转载请注明来源 Escape !