環境
預設以Python3為例,py2,3一些差別如下:
class的定義
Python3
class A:
def __init__(self):
pass
python2
class A(object):
def __init__(self):
pass
super()的調用
python3
class B(A):
def __init__(self):
super().__init__()
pass
python2
class B(A):
def __init__(self):
super(B,self).__init__()
pass
單繼承
這是我們平時見到的最多的情況,一個類繼承自另一個類。我們用一個小例子簡單說明:
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
b=B()
b.add(2)
print(b.n)
可以先算一下最後結果是多少,然後運作一下程式。
從結果看出,計算流程為:
B: self.n = 3 ---> A: self.n + 2 = 5 ---> B: self.n = self.n + 3 = 5 + 3 = 8
多繼承
多繼承就比較有意思了。
class A:
def __init__(self):
self.n = 2
def add(self, m):
print('self is {0} @A.add'.format(self))
self.n += m
class B(A):
def __init__(self):
self.n = 3
def add(self, m):
print('self is {0} @B.add'.format(self))
super().add(m)
self.n += 3
class C(A):
def __init__(self):
self.n = 4
def add(self, m):
print('self is {0} @C.add'.format(self))
super().add(m)
self.n += 4
class D(B, C):
def __init__(self):
self.n = 5
def add(self, m):
print('self is {0} @D.add'.format(self))
super().add(m)
self.n += 5
d=D()
d.add(2)
print(d.n)
強烈建議自己先算一下。
程式的最終輸出為:
程式執行的時候,調用到B類的時候,并沒有去調用A類,而是接着去調用C類的add方法,最後調用的A類的add方法。
我們來探究一下super究竟做了什麼。
探究super
super是一個類,我們調用super()的時候,實際上是執行個體化了一個super類。
class A: pass
s=super(A)
type(s)
#output is <class 'super'>
大多數情況下,super包含了兩個非常重要的資訊:
- MRO(Method Resolution Order)清單
- MRO的一個類
再來看多繼承中的例子。
d=D()
d.add(2)
print(d.n)
在python console,我們輸入
D.mro()
,對于Python2,是
D.__mro__
,傳回資訊為:
[<class '__main__.D'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.A'>, <class 'object'>]