Python 3.6中super()函数使用报错:调用父类方法出现属性错误
问题分析与解决方案
嘿,这个错误的根源其实是子类B没有继承父类A的flag属性,而且你对super()的用法可能有点误解,让我慢慢给你说清楚:
为什么会出现AttributeError?
当你让B继承A之后,你重写了B的__init__方法,但完全没有调用父类A的初始化方法。这就导致B的实例不会自动拥有A里定义的self.flag属性——毕竟__init__是用来初始化实例属性的,你覆盖了它却没继承父类的初始化逻辑,自然就找不到flag了。
另外,你可能误以为super().check_flag()会调用外部那个a实例的方法,但实际上super()的作用是让当前子类实例调用父类的方法逻辑,方法里的self仍然是B自己的实例,而不是你在主函数里创建的a实例。所以当check_flag里访问self.flag时,找的是B实例自己的flag,但这个属性根本不存在,就报错了。
修复方案分两种情况:
情况1:B实例用自己的flag属性
如果你只是想让B拥有自己的flag,只需要在B的__init__里调用父类的初始化方法就行:
class A: def __init__(self): self.flag = False def check_flag(self): return self.flag # 简化写法,无需多余的if-else判断 def create(self): b = B() b.foobar() class B(A): def __init__(self): super().__init__() # 调用父类A的__init__,初始化flag属性 self.foo = 0 def foobar(self): while not super().check_flag(): # 简化布尔判断写法 print("Works") if __name__ == "__main__": a = A() a.create()
这样B实例就有了自己的flag,调用super().check_flag()就能正常访问了。
情况2:B实例使用外部A实例(也就是主函数里的a)的flag
如果你的需求是让B用的是a实例的flag,那你需要把a的引用传递给B:
class A: def __init__(self): self.flag = False def check_flag(self): return self.flag def create(self): b = B(self) # 将当前A实例(a)传递给B b.foobar() class B: # 若仅需调用外部A实例的方法,无需继承A def __init__(self, parent_a): self.foo = 0 self.parent_a = parent_a # 保存外部A实例的引用 def foobar(self): while not self.parent_a.check_flag(): print("Works") if __name__ == "__main__": a = A() a.create()
这样B的foobar方法就会一直检查a实例的flag状态了。如果还是需要B继承A的其他方法,也可以保留继承关系,只是用parent_a来访问外部实例的属性即可。
内容的提问来源于stack exchange,提问作者medik ski
相关产品推荐
相关产品推荐

