python super __init__ 理解
代码解析1
先贴代码
代码来源
https://www.runoob.com/python/python-func-super.html
中的笔记
---> B ---
A --| |--> D
---> C ---
class A():
def __init__(self):
print('enter A')
print('leave A')
class B(A):
def __init__(self):
print('enter B')
super().__init__()
print('leave B')
class C(A):
def __init__(self):
print('enter C')
super().__init__()
print('leave C')
class D(B, C):
def __init__(self):
print('enter D')
super().__init__()
print('leave D')
d = D()
代码较为简单,D 集成 B 和 C 类 ,B 继承A,C也继承A。
结果
enter D
enter B
enter C
enter A
leave A
leave C
leave B
leave D
python根据MRO顺序进行调用父类的__init__函数,目的是不用重复初始化__init__,
代码解析2
如果不用super会导致重复初始化,
class A():
def __init__(self):
self.__a=1
print('enter A')
print('leave A')
class B(A):
def __init__(self):
self.__a=2
print('enter B')
# super().__init__()
A.__init__(self)
print('leave B')
class C(A):
def __init__(self):
self.__a=3
print('enter C')
# super().__init__()
A.__init__(self)
print('leave C')
class D(B, C):
def __init__(self):
self.__a=4
print('enter D')
# super().__init__()
B.__init__(self)
C.__init__(self)
print('leave D')
d = D()
print(d.__class__.__mro__)
代码运行结果为
enter D
enter B
enter A
leave A
leave B
enter C
enter A
leave A
leave C
leave D
(<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>)
可以看到 A 被多次初始化。
代码解析3
部分类使用super
class A():
def __init__(self):
self.__a=1
print('enter A')
print('leave A')
class B(A):
def __init__(self):
self.__a=2
print('enter B')
# super().__init__()
# A.__init__(self)
print('leave B')
class C(A):
def __init__(self):
self.__a=3
print('enter C')
# super().__init__()
# A.__init__(self)
print('leave C')
class D(B, C):
def __init__(self):
self.__a=4
print('enter D')
super().__init__() ##
# B.__init__(self)
# C.__init__(self)
print('leave D')
d = D()
print(d.__class__.__mro__)
运行结果
enter D
enter B
leave B
leave D
本来我以为 使用 super().init() 会使父类 B 和C 都初始化 但是 只执行了B 。
因为 super 是根据MRO表进行寻找的,整个过程只是用了一次 super().init() 所以根据MRO表,D的下一个是B 所以只初始化B
代码解析4
class A():
def __init__(self):
self.__a=1
print('enter A')
print('leave A')
class B(A):
def __init__(self):
self.__a=2
print('enter B')
super().__init__() ##
# A.__init__(self)
print('leave B')
class C(A):
def __init__(self):
self.__a=3
print('enter C')
# super().__init__()
# A.__init__(self)
print('leave C')
class D(B, C):
def __init__(self):
self.__a=4
print('enter D')
super().__init__() ##
# B.__init__(self)
# C.__init__(self)
print('leave D')
d = D()
print(d.__class__.__mro__)
运行结果
enter D
enter B
enter C
leave C
leave B
leave D
我们发现 在 B 类里的super().init() 并没调用 A 的 init 而是调用了C的。
结论
super只根据MRO表调用,下一个类的__init__ 不是 父类
另外,在 D 中执行两次 super().init() 只会初始化两次 B 类。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· 阿里巴巴 QwQ-32B真的超越了 DeepSeek R-1吗?
· 【译】Visual Studio 中新的强大生产力特性
· 2025年我用 Compose 写了一个 Todo App
· 张高兴的大模型开发实战:(一)使用 Selenium 进行网页爬虫
2020-03-28 windows word 打字 重复以及光标乱跳
2020-03-28 windows tensorflow gpu pip 安装