如何理解 Python 中 super() 与 __init__() 的配合使用?
子类重写 __init__ 时用 super().__init__() 调用父类构造方法,确保父类的初始化逻辑不被覆盖丢失。super 按 MRO 顺序查找父类。本文详解用法与常见坑。
子类重写 __init__ 时会覆盖父类的构造方法,父类的初始化逻辑(属性设置)会丢失。在子类 __init__ 里调用 super().__init__(...) 把父类那部分初始化补上。
基本用法
class Person:
def __init__(self, name):
self.name = name
class Student(Person):
def __init__(self, name, student_id):
super().__init__(name) # 调用父类构造,设置 self.name
self.student_id = student_id
s = Student("张三", "S001")
print(s.name) # 张三(来自父类初始化)
print(s.student_id) # S001
不调用 super().init 的后果
class Student(Person):
def __init__(self, name, student_id):
self.student_id = student_id # 忘了调 super
s = Student("张三", "S001")
print(s.name) # AttributeError——父类的 name 属性从未被设置
super() 的其他用法
class A:
def greet(self):
return "A"
class B(A):
def greet(self):
return super().greet() + " + B" # 在父类结果上扩展
print(B().greet()) # "A + B"
多继承与 MRO
super() 按 MRO(方法解析顺序)查找,多继承时不一定是"直接父类":
class C(B, A):
pass
print(C.__mro__) # 查看查找顺序
协作式多继承中每个类的 __init__ 都应调用 super().__init__() 并用 **kwargs 透传参数。
常见问题(FAQ)
Q:super() 必须写在 init 第一行吗?
A:不是硬性要求,但惯例是先调用父类初始化再设置子类属性——父类可能重置你的属性。
Q:父类没有定义 init 也要调 super 吗?
A:父类没写 __init__ 时会继承 object 的,不写 super 调用也没问题;但养成习惯,父类以后加了初始化代码就不用改子类。
Q:Python 2 的写法还能用吗?
A:super(Student, self).__init__(name) 是 Python 2 语法;Python 3 直接 super().__init__(name)。