📌1. super 的作用
super() 用来 调用父类(或兄弟类)的方法,而不用直接写父类名。
最典型的用法是:在子类重写了某个方法,但还想执行父类的方法逻辑:
class Animal:
def speak(self):
print("Animal makes a sound")
class Dog(Animal):
def speak(self):
super().speak() # 调用父类的 speak()
print("Dog barks")
dog = Dog()
dog.speak()
# 输出:
# Animal makes a sound
# Dog barks
📌2. 为什么不用直接写父类?
如果你写成 Animal.speak(self),确实也能调用,但有几个缺点:
不灵活:如果以后把父类换成了 Mammal,还要改所有 Animal.speak(self) 的地方。
多继承场景会出错:Python 支持多继承,直接写父类可能会破坏方法解析顺序(MRO),导致方法调用错乱。
📌3. super() 的工作原理(MRO)
super() 并不是“简单地找父类”,而是按照 方法解析顺序(MRO, Method Resolution Order) 查找下一个类。
示例:
class A:
def show(self):
print("A")
class B(A):
def show(self):
super().show()
print("B")
class C(A):
def show(self):
super().show()
print("C")
class D(B, C):
def show(self):
super().show()
print("D")
d = D()
d.show()
print(D.__mro__) # __mro__方法可以罗列D类的继承关系
# 输出:
# A
# C
# B
# D
# (<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
这里 D 继承了 B 和 C,MRO 顺序是:
D → B → C → A → object
所以 super() 会按照 MRO 顺序依次调用下一个类的方法。
📌4. 在 init 里用 super
初始化对象时,子类经常需要先执行父类的初始化逻辑:
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, student_id):
super().__init__(name) # 调用父类的 __init__
self.student_id = student_id
📌5. 注意事项
推荐用 super() 而不是 super(Class, self)(Python3 已经简化了写法)。
多继承时必须配合 super() 才能保证每个父类只被调用一次。
super 调用的是 MRO 下一个类的方法,不一定是“父类”。
🎯总结
super() 用来调用 MRO 顺序中的下一个方法。
在 继承 + 重写 的场景下特别常用(比如 Django 的 init、save 方法)。
它比直接写父类名更安全,更适合多继承。
300

被折叠的 条评论
为什么被折叠?



