Python跨模块访问类变量报NameError: name 'b'未定义是何原因
跨模块访问类变量报NameError的原因与修复方案
问题复现
mod1.py(定义B类的模块)
class B: varb = 10 def bkafunc(self): print("Mai B class ka func!")
触发报错的outmod1.py写法
from my_package.mod2 import B class outMod: b = B() def func_out_mod(self): print(b.varb) om = outMod() om.func_out_mod()
运行抛出异常:
NameError: name 'b' is not defined. Did you mean: 'B'?
可正常运行的临时写法
from my_package.mod2 import B class outMod: def func_out_mod(self): print(B().varb) om = outMod() om.func_out_mod()
运行结果:正常打印
varb的值10,但每次调用方法都会重复实例化B类,存在不必要的性能开销。
报错根本原因
这个报错和跨模块导入逻辑无关,核心是Python的作用域查找规则:
- 类定义的代码块是独立作用域,你在类体里直接写
b=B(),这个b是绑定在outMod类上的类属性,存在于outMod的类命名空间里,既不是模块级的全局变量,也不会自动进入类方法的局部作用域。 - 你在
func_out_mod方法里直接写b的时候,Python会按「方法局部变量→外层嵌套函数变量→模块全局变量→内置变量」的顺序查找名字,根本不会主动检索当前类的命名空间,自然找不到b,直接抛出NameError。 - 临时可运行版本的逻辑本质是:
B是导入到模块全局作用域的名字,方法里可以直接定位到B类,临时实例化之后取varb当然不会报错,但重复实例化的写法不符合资源复用的要求。
跨模块类变量的正确实现方式
根据业务场景选对应写法即可:
- 如果希望只实例化一次
B,所有outMod实例共用同一个B对象,就把b作为类属性,方法里通过类名或者实例引用访问:
from my_package.mod2 import B class outMod: b = B() # 类属性,所有outMod实例共享同个B实例 def func_out_mod(self): # 写法1:直接通过类名访问 print(outMod.b.varb) # 写法2:通过实例的类属性访问,不需要硬编码类名 # print(self.__class__.b.varb) om = outMod() om.func_out_mod()
- 如果希望每个
outMod实例单独持有一个独立的B实例,就把b绑定为实例属性,在初始化方法里赋值:
from my_package.mod2 import B class outMod: def __init__(self): self.b = B() # 实例属性,每个outMod实例单独持有一个B实例 def func_out_mod(self): print(self.b.varb) om = outMod() om.func_out_mod()
内容的提问来源于stack exchange,提问作者arin
相关产品推荐
相关产品推荐

