思考题 super()函数
思考题
# -*- coding:utf-8 -*-
class Bird():
def __init__(self):
self.hungry = True
def eat(self):
if self.hungry:
print(1)
else:
print(0)
# =============================================================================
# class Abird(Bird):
# def __init__(self):
# Bird.__init__(self)
# self.sound = 'aa'
#
# def sing(self):
# print(self.sound)
#
# class Cbird(Bird):
# def __init__(self):
# Bird.__init__(self)
# self.sound = 'cc'
#
# def sing(self):
# print(self.sound)
#
# class Dbird(Abird, Cbird):
# def __init__(self):
# Abird.__init__(self)
# Cbird.__init__(self)
# self.sound = 'dd'
#
# def sing(self):
# print(self.sound)
# =============================================================================
class Abird(Bird):
def __init__(self):
super(Abird, self).__init__()
self.sound = 'aa'
def sing(self):
print(self.sound)
class Cbird(Bird):
def __init__(self):
super(Cbird, self).__init__()
self.sound = 'cc'
def sing(self):
print(self.sound)
class Dbird(Abird, Cbird):
def __init__(self):
super(Abird, self).__init__()
super(Cbird, self).__init__()
self.sound = 'dd'
def sing(self):
print(self.sound)
if __name__ == '__main__':
d = Dbird()
print(d.eat())
print(d.hungry)
print(d.sing())
print(d.sound)
菱形继承潜在的问题:一个基类的初始化函数可能被调用两次。在一般的工程中,这显然不是我们所希望的。正确的做法应该是使用 super 来召唤父类的构造函数,而且 python 使用一种叫做方法解析顺序的算法(具体实现算法叫做 C3),来保证一个类只会被初始化一次。 看答案后重新整理
class A(object):
def __init__(self):
print('enter A')
print('leave A')
class B(A):
def __init__(self):
A.__init__(self)
print('enter B')
print('leave B')
class C(A):
def __init__(self):
A.__init__(self)
print('enter C')
print('leave C')
class D(B, C):
def __init__(self):
B.__init__(self)
C.__init__(self)
print('enter D')
print('leave D')
D()
enter A
leave A
enter B
leave B
enter A
leave A
enter C
leave C
enter D
leave D
继承的MRO问题
# MRO 测试:Python3唯一支持的方式-C3算法
# 延用从左至右的深度优先遍历,但是如果遍历中出现重复的类,只保留最后一个
class D(object): pass
class E(object): pass
class F(object): pass
class B(D, E): pass
class C(D, F): pass
class A(B, C): pass
A.__mro__
Out[25]:
(__main__.A,
__main__.B,
__main__.C,
__main__.D,
__main__.E,
__main__.F,
object)
class A(object): pass
class B(A): pass
class C(A): pass
class D(B, C): pass
D.__mro__
Out[30]: (__main__.D, __main__.B, __main__.C, __main__.A, object)
super()函数 解决多继承,涉及到的查找顺序(MRO)、重复调用(钻石继承)等种种问题。 Tips: 当需要调用继承类中的多个函数时,需使用cls._init _(self)