python 多继承 init_python m序列python 多继承详解

本文通过一个具体的例子探讨了Python多继承中`__init__`调用的复杂性,指出在某些情况下,初始化函数可能会被重复调用。通过分析类的MRO(Method Resolution Order)顺序,解释了为何会出现这样的现象。通过引入`super`关键字并修改代码,确保每个父类的初始化函数只被调用一次,避免了重复。文章强调了理解`super`工作原理和MRO的重要性。
摘要由CSDN通过智能技术生成

在我们的印象中,对于super(B, self).__init__()是这样理解的:super(B, self)首先找到B的父类(就是类A),然后把类B的对象self转换为类A的对象,然后“被转换”的类A对象调用自己的__init__函数。有一天某同事设计了一个相对复杂的类体系结构(我们先不要管这个类体系设计得是否合理,仅把这个例子作为一个题目来研究就好),代码如下

代码段4:class A(object):

def __init__(self):

print "enter A"

print "leave A"

class B(object):

def __init__(self):

print "enter B"

print "leave B"

class C(A):

def __init__(self):

print "enter C"

super(C, self).__init__()

print "leave C"

class D(A):

def __init__(self):

print "enter D"

super(D, self).__init__()

print "leave D"

class E(B, C):

def __init__(self):

print "enter E"

B.__init__(self)

C.__init__(self)

print "leave E"

class F(E, D):

def __init__(self):

print "enter F"

E.__init__(self)

D.__init__(self)

print "leave F"

f = F() ,结果如下:enter F enter E enter B leave B enter C enter D enter A leave A leave D leave C leave E enter D enter A leave A leave D leave F

明显地,类A和类D的初始化函数被重复调用了2次,这并不是我们所期望的结果!我们所期望的结果是最多只有类A的初始化函数被调用2次——其实这是多继承的类体系必须面对的问题。我们把代码段4的类体系画出来,如下图:

《python m序列python 多继承详解》总结了关于Python基础教程教程,对于我们来电脑技术网确实能学到不少知识。

object   |         |        A   |      / |   B  C  D       /   |      E    |           |          F

按我们对super的理解,从图中可以看出,在调用类C的初始化函数时,应该是调用类A的初始化函数,但事实上却调用了类D的初始化函数。好一个诡异的问题!

也就是说,mro中记录了一个类的所有基类的类类型序列。查看mro的记录,发觉包含7个元素,7个类名分别为:

F E B C D A object

从而说明了为什么在C.__init__中使用super(C, self).__init__()会调用类D的初始化函数了。 ???

我们把代码段4改写为:代码段5:class A(object):

def __init__(self):

print "enter A"

super(A, self).__init__() # new

print "leave A"

class B(object):

def __init__(self):

print "enter B"

super(B, self).__init__() # new

print "leave B"

class C(A):

def __init__(self):

print "enter C"

super(C, self).__init__()

print "leave C"

class D(A):

def __init__(self):

print "enter D"

super(D, self).__init__()

print "leave D"

class E(B, C):

def __init__(self):

print "enter E"

super(E, self).__init__() # change

print "leave E"

class F(E, D):

def __init__(self):

print "enter F"

super(F, self).__init__() # change

print "leave F"

f = F(),执行结果:enter F enter E enter B enter C enter D enter A leave A leave D leave C leave B leave E leave F可见,F的初始化不仅完成了所有的父类的调用,而且保证了每一个父类的初始化函数只调用一次。

小结

1. super并不是一个函数,是一个类名,形如super(B, self)事实上调用了super类的初始化函数,       产生了一个super对象;  2. super类的初始化函数并没有做什么特殊的操作,只是简单记录了类类型和具体实例;

更多:python m序列python 多继承详解

https://www.002pc.comhttps://www.002pc.com/python/2065.html

你可能感兴趣的python,详解,继承

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值