Python跨文件引用main模块变量触发重初始化及属性丢失问题求助
问题根因
这是典型的Python循环导入导致的模块半加载问题,不是属性被清空,而是Weather模块的加载流程被强制中断,后续代码没有执行:
- 运行
main.py时,解释器从上到下执行代码,执行到import Weather行时,暂停main.py的执行,开始加载Weather.py - 加载
Weather.py时,执行到from main import DISPLAY_W, DISPLAY_H行,再次暂停Weather.py的执行,转回加载main.py - 此时解释器发现
main.py已经在加载流程中,不会重复执行全量代码,只会返回当前半初始化的main模块对象,而你的DISPLAY_W、DISPLAY_H定义在import Weather行之后,此时还没被创建,同时Weather.py的加载一直卡在导入main的步骤,后续的函数、变量定义代码完全没执行,所以最终拿到的Weather模块只有前两行导入的pygame属性,其余自定义内容都不存在。
解决方案
下面三个方案按推荐优先级排序:
- 方案1:抽离独立配置模块(最优)
新建单独的config.py存放所有跨文件共享的常量,从根源上避免循环依赖:
之后# config.py DISPLAY_W = 800 DISPLAY_H = 800 # 其余所有全局共享常量都可以放在这里main.py和Weather.py都从config导入常量即可,不需要互相导入:
该方案架构清晰,后续新增共享变量也不会再出现循环导入问题。# main.py / Weather.py 中都写 from config import DISPLAY_W, DISPLAY_H - 方案2:调整导入顺序
不想新增文件的话,可以把main.py中常量定义的代码移到import Weather之前,确保加载Weather时main的常量已经初始化完成:# main.py import pygame import glob from random import * from pygame import mixer import TileSheet import Button # 先完成初始化、定义常量 pygame.init() DISPLAY_W, DISPLAY_H = 800, 800 canvas = pygame.Surface((DISPLAY_W, DISPLAY_H)) screen = pygame.display.set_mode((DISPLAY_W, DISPLAY_H)) pygame.display.set_caption('Test Tileset') running = True # 最后再导入Weather import Weather - 方案3:使用延迟导入
如果你一定要从main模块读取变量,就不要在模块顶层写导入语句,改为在需要用到变量的函数内部导入,此时main模块已经完全加载完成,不会触发循环导入:# Weather.py import pygame from random import * def initialize_weather(): # 仅在函数内部导入,函数调用时才执行 from main import DISPLAY_W, DISPLAY_H # 后续业务逻辑
内容的提问来源于stack exchange,提问作者user15434531
相关产品推荐
相关产品推荐

