如何理解 Python 中 super() 与 __init__() 的配合使用?

子类重写 __init__ 时用 super().__init__() 调用父类构造方法,确保父类的初始化逻辑不被覆盖丢失。super 按 MRO 顺序查找父类。本文详解用法与常见坑。

最佳实践
如何理解 Python 中 super() 与 __init__() 的配合使用?封面

子类重写 __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)

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台