Python自导入模块时全局变量输出结果异常原因求解
Python导入自身模块异常输出逻辑分析
问题复现代码
# main.py var = 99 def importModule(): import main print(main.var, end='>inside ') main.var = 0 importModule() print(var, end='>outside ')
实际输出:99>inside 0>outside 0>inside 99>outside
核心前置知识
- Python直接运行脚本时,该脚本对应的模块名称为
__main__,而非脚本文件名 - import导入模块时会先检查
sys.modules缓存,缓存中不存在对应名称的模块时,会加载并执行对应文件的全部顶层代码,生成模块对象存入缓存 - 不同名称的模块即使对应同一个文件,也是完全独立的对象,拥有各自隔离的全局命名空间
逐步骤执行逻辑
- 步骤1:执行
python main.py启动程序,当前运行模块为__main__:- 执行顶层代码,给
__main__.var赋值为99 - 定义函数
importModule,暂不执行内部逻辑 - 调用
importModule()进入函数
- 执行顶层代码,给
- 步骤2:
__main__.importModule函数内执行import main:- 检查
sys.modules无main模块缓存,重新加载main.py文件,生成名为main的模块对象,执行该模块的所有顶层代码:- 给
main.var赋值为99 - 定义
main.importModule函数 - 调用
main.importModule()进入该函数 main.importModule内执行import main:sys.modules已有main缓存,直接返回已有模块对象- 打印
main.var的值99,输出第一段内容99>inside - 将
main.var修改为0,退出main.importModule函数 - 回到
main模块顶层最后一行代码,打印当前模块的var即main.var,值为0,输出第二段内容0>outside
- 给
import main执行完成,返回已加载的main模块对象
- 检查
- 步骤3:回到
__main__.importModule函数后续逻辑:- 打印
main.var的值,此时已经被修改为0,输出第三段内容0>inside - 将
main.var再次赋值为0,无实际变化,退出__main__.importModule函数
- 打印
- 步骤4:回到
__main__模块顶层最后一行代码:- 打印当前模块的
var即__main__.var,全程未被修改仍为99,输出第四段内容99>outside
- 打印当前模块的
所有输出拼接后和实际运行结果完全一致。
内容的提问来源于stack exchange,提问作者qiao
相关产品推荐
相关产品推荐

