__init__ 初始化方法

下面讲python中, __init__ 在继承里最常见、最容易踩的坑

核心一句话

子类写了 __init__,就不会自动调用父类 __init__

父类的初始化代码不会自动跑,属性、逻辑都会丢。


坑 1:子类写了 init ,但没调用父类 init

错误代码

python 复制代码
class Animal:
    def __init__(self):
        print("父类初始化")
        self.age = 10  # 父类属性

class Dog(Animal):
    def __init__(self):
        print("子类初始化")
        # 这里没调用父类 __init__!

dog = Dog()
print(dog.age)  # 报错!AttributeError

为什么错?

  • 子类自己写了 __init__
  • Python 不会自动帮你调父类的 __init__
  • 所以 self.age 根本没被创建
  • 访问就报错

正确写法

python 复制代码
class Dog(Animal):
    def __init__(self):
        super().__init__()  # 手动调用父类初始化
        print("子类初始化")

坑 2:父类 init 需要参数,子类没传

错误代码

python 复制代码
class Animal:
    def __init__(self, age):
        self.age = age

class Dog(Animal):
    def __init__(self):
        super().__init__()  # 没传 age!

运行直接报错:
TypeError: __init__() missing 1 required positional argument: 'age'

正确写法

python 复制代码
class Dog(Animal):
    def __init__(self):
        super().__init__(10)  # 传参

坑 3:以为 super() 必须带类名和 self(老写法误区)

Python3 里下面两种完全一样

python 复制代码
super().__init__()

# 老写法(Python2 遗留)
super(Dog, self).__init__()

你只需要记:
Python3 直接写 super().__init__() 就够了


坑 4:多继承时 super() 调用顺序混乱(菱形问题)

这个是最难、最容易懵的坑。

python 复制代码
class A:
    def __init__(self):
        print("A")

class B(A):
    def __init__(self):
        print("B")
        super().__init__()

class C(A):
    def __init__(self):
        print("C")
        super().__init__()

class D(B, C):
    def __init__(self):
        print("D")
        super().__init__()

d = D()

你以为执行顺序是:

D → B → A

D → C → A

实际输出:

复制代码
D
B
C
A

为什么?

因为 Python 多继承用 MRO 方法解析顺序
super() 不是"只调父类",而是按 MRO 链找下一个。

结论

多继承里 super() 行为很诡异,尽量少用多继承

这也是为什么设计原则说:优先组合,少用继承


坑 5:子类 init 里还没 super 就用父类属性

python 复制代码
class Animal:
    def __init__(self):
        self.age = 10

class Dog(Animal):
    def __init__(self):
        print(self.age)   # 报错!还没初始化
        super().__init__()

必须先调用 super().__init__(),才能用父类属性。


最核心总结(背这几句就够)

  1. 子类写 __init__,必须手动调用 super().__init__()
  2. 父类要参数,子类必须传
  3. super(),再用父类属性
  4. 多继承 super() 顺序诡异 → 尽量不用多继承
  5. 子类不写 __init__ → 自动用父类的,不会踩坑

相关推荐
m0_377618231 小时前
SQL如何解决GROUP BY导致查询变慢_利用覆盖索引进行优化
jvm·数据库·python
java1234_小锋1 小时前
LangChain4j快速入门
人工智能·python·spring
qq_334563551 小时前
如何提高SQL存储过程可维护性_解耦复杂业务逻辑
jvm·数据库·python
Rust研习社1 小时前
Rust 并发同步:Mutex 与 RwLock 智能指针
开发语言·后端·rust
2301_777599371 小时前
Golang map底层实现原理_Golang map哈希表原理教程【收藏】
jvm·数据库·python
2301_813599551 小时前
Go语言怎么用AWS S3_Go语言S3对象存储教程【总结】
jvm·数据库·python
code_li1 小时前
▍Type-C 不等于 Type-C,是看起来已经「统一」了
c语言·开发语言·type-c
程序员科科1 小时前
2026最新ChatGPT Plus会员优惠充值,轻松使用GPT-5
python
geovindu1 小时前
go: Abstract Factory Pattern
开发语言·后端·设计模式·golang