Python 3.x中类C含super().method引发报错的原因解析
为什么移除类C的
super().method()后代码就不报错了? 问题现象
以下Python代码运行时会触发AttributeError: 'super' object has no attribute 'method'错误,但删除类C中的super().method()调用后,代码可正常运行:
class A(object): def method(self): print("\n class A method") super().method() class B(object): def method(self): print("\n class B method") super().method() class C(object): def method(self): print("\n class C method") super().method() class X(A, B): def method(self): print("\n class X method") super().method() class Y(B, C): def method(self): print("\n class Y method") super().method() class P(X, Y, C): def method(self): print("\n class P method") super().method() p = P() p.method() print(P.mro())
原因解析
1. super()的真实作用
别被名字误导,super()不是直接调用当前类的父类方法,它的核心逻辑是:根据当前实例所属类的「方法解析顺序(MRO)」,找到MRO列表里当前类的下一个类,调用该类的对应方法——和当前类的直接父类没有必然绑定关系。
2. 先看P类的MRO顺序
运行代码里的print(P.mro()),会得到P类的方法解析顺序:[<class '__main__.P'>, <class '__main__.X'>, <class '__main__.A'>, <class '__main__.Y'>, <class '__main__.B'>, <class '__main__.C'>, <class 'object'>]
3. 追踪报错的调用链
当调用p.method()时,会严格按照MRO顺序逐层调用:
P.method()打印后,通过super()找到MRO下一个类X,调用X.method()X.method()打印后,通过super()找到A,调用A.method()A.method()打印后,通过super()找到MRO里A的下一个类Y(不是A的父类object),调用Y.method()Y.method()打印后,通过super()找到B,调用B.method()B.method()打印后,通过super()找到C,调用C.method()C.method()打印后,通过super()找到MRO里C的下一个类object,但object根本没有定义method方法,直接抛出AttributeError
4. 移除C的super().method()为什么就正常了?
删掉C类里的super().method()后,C.method()执行完打印就终止了整个调用链,不会去尝试调用object的method,自然不会触发错误。
内容的提问来源于stack exchange,提问作者Sandeep Chetia
相关产品推荐
相关产品推荐

