如何在导入不可修改的temp.py时执行其if __name__ == "__main__"下的代码
可行解决方案
核心逻辑为:if __name__ == "__main__"分支的触发条件仅为当前运行的模块__name__属性值等于__main__,只需在导入temp模块时手动修改对应属性值,即可在不修改原文件的前提下触发目标代码执行,同时保证模块被完整导入。
方案1:使用importlib标准库加载模块(推荐,完全替代已废弃的imp模块)
import importlib.util import sys # 指定temp.py的文件路径和模块名,生成模块加载规范 spec = importlib.util.spec_from_file_location("temp", "./temp.py") # 构造空的temp模块对象 temp_module = importlib.util.module_from_spec(spec) # 临时将模块的__name__设置为__main__,满足分支触发条件 temp_module.__name__ = "__main__" # 将模块注册到全局模块缓存,保证后续所有import temp操作拿到同一个实例 sys.modules["temp"] = temp_module # 执行模块内所有代码,此时会触发if __name__ == "__main__"分支 spec.loader.exec_module(temp_module) # 可选:执行完成后改回原模块名,避免后续逻辑出现异常 temp_module.__name__ = "temp" # 后续可以正常使用temp_module的所有属性、函数、类,和常规导入效果完全一致
方案2:手动执行模块源码
适合需要自定义更多执行上下文的场景:
import sys from types import ModuleType # 构造模块实例 temp_module = ModuleType("temp") # 注册到模块缓存 sys.modules["temp"] = temp_module # 读取temp.py的源码内容 with open("temp.py", "r", encoding="utf-8") as f: source_code = f.read() # 执行源码,手动指定__name__为__main__,同时传入必要的内置属性 exec( source_code, { "__name__": "__main__", "__file__": "temp.py", "__builtins__": __builtins__ }, temp_module.__dict__ )
注意事项
- 如果
temp.py的if __name__ == "__main__"分支内依赖sys.argv等命令行参数,需要在执行前手动给sys.argv赋值为预期的参数列表,避免运行报错 - 两种方案都无需修改
temp.py的源码,所有操作都在你自主编辑的文件内完成 - 最终得到的
temp_module和常规导入的模块完全一致,所有全局变量、函数、类都可以正常访问
内容的提问来源于stack exchange,提问作者Jithin Johnson
相关产品推荐
相关产品推荐

