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

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链:

  1. 调用Animal.__init__,里面的super().__init__(name)触发MRO下一个类canFly的__init__
  2. canFly.__init__打印Dog cannot fly,然后调用super().__init__——这里的super指向MRO中canFly的下一个类canSwim,而不是直接指向Mammal
  3. canSwim.__init__打印Dog cannot swim,同样调用super()指向MRO下一个类canWagTail
  4. canWagTail.__init__打印Dog can wag tail,调用super()指向MRO下一个类Mammal
  5. 最后执行Mammal.__init__,打印Dog Is a mammal

3. 为什么没有重复打印Mammal的输出?

你的预期误区在于认为每个子类的super()会直接调用Mammal,但在多继承的MRO链中,super()是沿着整个链依次调用,直到链的末端。只有当走到Mammal时才会执行它的构造方法,所以不会出现多次打印Is a mammal的情况。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 19:53:02