如何理解 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__)   # 查看查找顺序

协作式多继承需全链路约定:各类消费自身参数,把剩余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)。

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

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

立即开始

选择观测云版本

代码托管平台