简介

在 Python 的官方文档中,记录了 python 命令的 -m <module-name> 参数:

sys.path 中搜索指定名称的模块并将其内容作为 __main__ 模块来执行。

例如,有以下目录结构:

.
└── foo
    └── bar.py

则可以通过 python -m foo.bar 运行 bar.py 文件。

与普通运行方式的不同

主要区别在于 sys.pathsys.modules 的设置。假设项目路径为 /Users/chi/Projects/j4t

普通运行方式(例如 python foo/bar.py):

  • sys.path 中包含路径 /Users/chi/Projects/j4t/foo
  • sys.modules 中的 __main__<module '__main__' from 'foo/bar.py'>
  • __file__ 的值为 foo/bar.py

-m 运行方式(例如 python -m foo.bar):

  • sys.path 中包含路径 /Users/chi/Projects/j4t
  • sys.modules 中的 __main__<module 'foo.bar' from '/Users/chi/Projects/j4t/foo/bar.py'>
  • __file__ 的值为 /Users/chi/Projects/j4t/foo/bar.py

可以看到,-m 方式将执行时的当前目录加入到 PYTHONPATH 中,而不是目标文件所在的目录。这种差异可能影响模块导入和其他运行时行为。

用途

可以使用 -m 方式来执行单元测试。例如,以下项目结构:

.
├── src
└── tests

在未安装 src 模块的情况下,可以在 tests 目录的测试用例中直接导入 src 作为模块,然后使用 python -m pytest 执行测试。此时,由于 sys.path 中包含当前目录,src 模块能够被正确搜索到。

参考