Python多继承中super()构造函数调用行为异常咨询
Python多继承中super()的调用机制解析
用户代码
class Mammal(object): def __init__(self, name): print(name, "Is a mammal") class canFly(Mammal): def __init__(self, canFly_name): print(canFly_name, "cannot fly") super().__init__(canFly_name) class canSwim(Mammal): def __init__(self, canSwim_name): print(canSwim_name, "cannot swim") super().__init__(canSwim_name) class canWagTail(Mammal): def __init__(self, canWag_name): print(canWag_name, "can wag tail") super().__init__(canWag_name) class Animal(canFly, canSwim, canWagTail): def __init__(self, name): super().__init__(name) Carol = Animal("Dog")
预期输出
Dog cannot fly Dog is a mammal
实际输出
Dog cannot fly Dog cannot swim Dog can wag tail Dog Is a mammal
问题解析
1. super()的核心:方法解析顺序(MRO)
Python多继承里,super()不是直接调用当前类的父类方法,而是按照**MRO(Method Resolution Order)**列表,调用链中的下一个类的对应方法。每个类的MRO是Python根据继承关系自动生成的线性序列,保证每个类只被调用一次。
你可以打印Animal.__mro__查看具体顺序:
print(Animal.__mro__) # 输出:(<class '__main__.Animal'>, <class '__main__.canFly'>, <class '__main__.canSwim'>, <class '__main__.canWagTail'>, <class '__main__.Mammal'>, <class 'object'>)
2. 代码执行的完整流程
当你实例化Animal("Dog")时,执行顺序完全遵循MRO链:
- 调用
Animal.__init__,里面的super().__init__(name)触发MRO下一个类canFly的__init__ canFly.__init__打印Dog cannot fly,然后调用super().__init__——这里的super指向MRO中canFly的下一个类canSwim,而不是直接指向MammalcanSwim.__init__打印Dog cannot swim,同样调用super()指向MRO下一个类canWagTailcanWagTail.__init__打印Dog can wag tail,调用super()指向MRO下一个类Mammal- 最后执行
Mammal.__init__,打印Dog Is a mammal
3. 为什么没有重复打印Mammal的输出?
你的预期误区在于认为每个子类的super()会直接调用Mammal,但在多继承的MRO链中,super()是沿着整个链依次调用,直到链的末端。只有当走到Mammal时才会执行它的构造方法,所以不会出现多次打印Is a mammal的情况。
内容的提问来源于stack exchange,提问作者xyz
相关产品推荐
相关产品推荐

