目录

使用python -m运行

简介

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

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

例如有以下目录结构:

1
2
3
.
└── foo
    └── bar.py

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

与普通运行方式的不同

不同点主要在于 sys.pathsys.modules。假设项目路径为 /Users/chi/Projects/j4t

普通运行方式:

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

-m 运行方式:

  • 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 方式来执行单元测试,例如以下项目结构:

1
2
3
.
├── src
└── tests

在没有安装 src 模块的情况下,在 tests 目录的测试用例中,直接将 src 作为模块 import,然后执行时使用 python -m pytest 就可以。

因为此时 sys.path 中含有当前目录,因此 src 能够被搜索到。

参考