如何理解 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__) # 查看查找顺序
协作式多继承需全链路约定:各类消费自身参数,把剩余kwargs传给super,最终object.__init__不接受多余参数。__init__负责初始化已创建的对象,__new__负责创建对象。
常见问题(FAQ)
Q:super() 必须写在 init 第一行吗?
A:不是硬性要求,但惯例是先调用父类初始化再设置子类属性——父类可能重置你的属性。
Q:父类没有定义 init 也要调 super 吗?
A:应检查MRO中下一个实际初始化方法,可能来自其他祖先,不一定直接是object;但养成习惯,父类以后加了初始化代码就不用改子类。
Q:Python 2 的写法还能用吗?
A:super(Student, self).__init__(name) 是Python3仍支持的双参数形式;Python3实例方法通常可直接 super().__init__(name)。