__name__ == "__main__"是唯一可靠方式,因Python语言层面保证其值在直接执行时为"__main__"、导入时为模块名,不依赖外部参数或环境变量。
__name__ == "__main__" 是唯一可靠方式Python 没有内置的“运行模式”变量,__name__ 的值是解释器在加载模块时自动设置的:被直接执行时为 "__main__",被 import 时为模块文件名(不含 .py)。这是语言层面保证的行为,不依赖进程参数、文件路径或环境变量,所以其他方法(比如检查 sys.argv[0] 或当前工作目录)都可能在特定场景下失效——例如通过 python -m module_name 运行时,__name__ 仍是 "__main__",但 sys.argv[0] 是 "-m"。
if __name__ == "__main__": 的典型用法和常见误写这个判断必须出现在模块顶层(不能缩进),且只能用于控制“是否执行某段逻辑”,不能用来改变模块导出内容(如动态删函数或改 __all__)。
if __name__ == "__main__": def helper(): ... —— 这会让函数只在运行时存在,被 import 后无法使用if __name__ is "__main__": —— 字符串比较必须用 ==,is 依赖字符串驻留机制,在某些 Python 实现或优化级别下可能失败python -m 执行时的行为差异用 python -m mypackage.mymodule 运行时,模块仍被视为脚本入口,__name__ 是 "__main__",但 __file__ 可能是 None(尤其对 zip 包里的模块),且 sys.path[0] 是空字符串而非文件所在目录。这意味着:

__file__ 计算相对路径的代码会报 TypeError
-m 方式,应改用 pathlib.Path(__file__).resolve().parent 前加 if __file__: 判断if __name__ == "__main__": 本身不受影响,照常生效单元测试中常需要验证模块被 import 后的状态(比如全局变量是否初始化、函数是否可调用),而不是运行其 if __name__ == "__main__" 块。这时不能直接 import mymodule,因为模块一旦导入,__name__ 就固定了,重复 import 不会重新执行顶层代码。
importlib.util.spec_from_file_location + importlib.util.module_from_spec 动态加载,绕过缓存sys.modules 中对应模块名(如 del sys.modules["mymodule"]),再 import__name__ = "mymodule" —— 这只是改了局部变量,不影响解释器实际行为-m 场景下的 __file__ 为 None,以及测试时没清理 sys.modules 导致判断逻辑被缓存掩盖。