Python如何使用类实现跨两文件全局变量(解决循环导入)
问题原因
当前的循环导入是模块加载顺序导致的:
运行a.py时,解释器第一步就执行from b import func1,触发b.py加载;而b.py加载时第一时间要从a.py导入user_g,但此时a.py连My_Globals类都还没定义完,根本不存在user_g这个变量,自然报错。
基于类实现跨脚本全局变量的方案
你不需要额外新建第三个文件存全局变量,用Python类的特性就能实现全局可访问、无需传参的效果,同时规避循环导入。
方案1:最小改动,延迟导入
不用改现有类和实例的逻辑,只要把b.py里的导入动作从顶层挪到函数内部,避开模块加载阶段的循环引用即可:
修改后的b.py代码:
def func1(): # 函数实际调用时才会执行导入,此时a.py已经完成user_g的初始化 from a import user_g print(user_g.g)
a.py完全不用改,直接运行就能正常输出kkk。这个方案的前提是func1只会在a.py完成user_g初始化之后调用,你的现有代码刚好满足这个条件。
方案2:用类属性做全局命名空间(更稳定)
如果希望全局变量可以在任意位置读写、不依赖调用顺序,可以把类设计成纯类属性的全局容器,不用实例化,所有导入这个类的脚本共享同一份属性值:
首先调整a.py的代码顺序,把导入b的动作放到类定义和全局值初始化之后:
# a.py class My_Globals: # 类属性全局共享 global1 = "" global2 = "" g = "" # 初始化全局值 My_Globals.global1 = "abc" My_Globals.global2 = "def" My_Globals.g = "kkk" # 等全局类初始化完再导入b的函数,不会出现拿不到定义的问题 from b import func1 func1()
对应的b.py只需要导入类本身:
# b.py from a import My_Globals def func1(): # 直接访问类属性拿全局值,不需要传参 print(My_Globals.g)
这个方案的逻辑很简单:Python的类本身是一等对象,类属性在所有导入这个类的位置都是同一份引用,修改会全局生效,天然适合做小型脚本的全局状态容器,完全满足你“通过类实现全局变量公开访问”的需求。
补充说明
你提到的新建独立文件存放全局变量的方案是中大型项目更推荐的做法,能彻底避免业务模块间的循环依赖,但如果是轻量脚本不想拆分多余文件,上面两个方案都可以正常使用。
内容的提问来源于stack exchange,提问作者Lixiang Wei
相关产品推荐
相关产品推荐

