关于命令行:如何知道是否使用解释器的-m选项运行python脚本?

How to know if python script was run using interpreter's -m option?

阅读完所有内容后,我找不到答案:

  • PEP 338将模块作为脚本执行
  • runpy标准模块的文档
  • Python解释器的-m选项的描述

理由:
当在没有-m选项的情况下运行使用相对导入的测试脚本时,我可以打印警告消息,而不是让用户使用标准回溯导致ValueError: Attempted relative import in non-package异常。 在不知道这一点的情况下,我可以捕获此异常并且仅表明缺少-m选项可能是错误的原因。


免责声明:这只是一个观察,我没有在文档中看到它,因此它可能是依赖于实现的,并且可能在不同的Python版本中不一致。

我注意到当使用-m选项调用脚本时,名为__loader__的变量被添加到命名空间中,因此在脚本的顶部可以检查该变量是否存在:

1
2
if '__loader__' in globals():
    # called with -m

为了一些额外的安全性,您可以检查__loader__是否是pkgutil.ImpLoader的实例:

1
if '__loader__' in globals() and __loader__.__class__.__name__ == 'ImpLoader':


另一个观察是,当使用-m时,__package__设置为None,当使用-m时,设置为包名称(当模块未包含在任何包中时使用空字符串,因此它仍然不同于None)。