You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python子类访问父类__slots__槽变量报AttributeError

问题产生原因
  • dir() 列出属性名不代表实例已经为该属性完成赋值。__slots__ 的本质是在类层级为实例声明固定的属性存储槽位,会为每个槽生成对应的数据描述符,只要类或任意父类在__slots__中声明了某属性,dir()就会将该属性名纳入输出列表。但槽位只是预留了存储空间,若从未给该属性赋值,槽的描述符在被访问时会直接抛出AttributeError,和普通实例属性未赋值就访问的报错逻辑一致。
  • 父类初始化逻辑完全未执行。你在Child1的__init__方法中仅写了super(),这行代码仅生成了一个父类代理对象,没有调用任何方法,属于无效代码。Base1.__init__中给slot_0、slot_1赋值的逻辑从未被触发,两个槽位虽然存在,但始终没有被写入值,自然访问报错。
修复与正确访问方式

核心是要正确调用MRO链上所有类的初始化方法,保证父类中为槽赋值的逻辑正常执行,修复后的代码如下:

class Base1():
   __slots__ = ["slot_0", "slot_1"]

   def __init__(self):
       self.slot_0 = "zero"
       self.slot_1 = "one"
       super().__init__() # 多继承场景下需要调用,保证MRO链后续类初始化执行

   def baseFunc(self):
          print("nice1")

class Base2():
    __slots__ = []

    def __init__(self):
        super().__init__()
        pass

    def baseFunc2(self):
        print("nice2")

class Child1(Base1, Base2):
    __slots__ = ["slot_00", "slot_11"]

    def __init__(self):
        self.slot_00 = "zero"
        self.slot_11 = "one"
        super().__init__() # 正确调用父类初始化方法,而非仅写super()

    def newFunc(self):
        print("nice")

c1 = Child1()
print(c1.slot_0) # 正常输出 zero
print(c1.slot_1) # 正常输出 one

如果不需要父类给槽设置默认值,也可以在实例化子类后手动给继承来的槽位赋值,赋值后即可正常访问:

c1 = Child1()
c1.slot_0 = "自定义值"
print(c1.slot_0) # 正常输出 自定义值

注意:不存在“子类无法访问父类定义的槽变量”的限制,只要子类没有在自身__slots__中声明同名属性覆盖父类槽,就可以正常读写父类声明的槽位,唯一前提是该槽位已经被赋值。

内容的提问来源于stack exchange,提问作者ThreadBucks

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 05:15:54