如何判断 Python 脚本是否通过解释器的 -m 选项运行?

9 投票
2 回答
1309 浏览
提问于 2025-04-17 07:30

我在看完以下内容后还是找不到答案:

背景说明:
当我运行一个使用相对导入的测试脚本,而没有加上 -m 选项时,我希望能打印出一个警告信息,而不是让用户看到标准的错误追踪信息,导致出现 ValueError: Attempted relative import in non-package 的异常。如果我不知道这一点,我可能会捕获到这个异常,但只能建议用户缺少 -m 选项可能是错误的原因。

2 个回答

3

免责声明:这只是我的一个观察,我在文档中没有看到相关内容,所以这可能和具体的实现有关,并且在不同的Python版本中可能不一致。

我注意到,当使用 -m 选项来调用一个脚本时,会在命名空间中添加一个叫 __loader__ 的变量。因此,在你的脚本开头,你可以检查一下这个变量是否存在:

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

为了增加一些安全性,你可以检查一下 __loader__ 是否是 pkgutil.ImpLoader 的一个实例:

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

另一个观察是,当直接运行脚本时,__package__ 的值会被设置为 None;而当使用 -m 选项时,它会被设置为包的名称。如果这个模块不属于任何包,它的值会是空字符串,这和 None 还是不一样的。

撰写回答