鑽石問題主要關注如下兩個問題(參考文章:python 多重繼承的事):
父類方法的呼叫順序上(下面一小節)
比如若b和c中的m方法也同時呼叫了a中的m方法時,重複執行的問題
class a:
def m(self):
print("m of a called")
class b(a):
def m(self):
print("m of b called")
a.m(self)
class c(a):
def m(self):
print("m of c called")
a.m(self)
class d(b,c):
def m(self):
print("m of d called")
b.m(self)
c.m(self)
輸出結果:
m of d called
m of b called
m of a called
m of c called
m of a called
其實上面兩個問題的根源都跟mro有關,mro(method resolution order)也叫方法解析順序,主要用於在多重繼承時判斷調的屬性來自於哪個類,其使用了一種叫做c3的演算法,其基本思想時在避免同一類被呼叫多次的前提下,使用廣度優先和從左到右的原則去尋找需要的屬性和方法。
問題二的解決方案如下:
class a(object):
def m(self):
print("m of a called")
class b(a):
def m(self):
print("m of b called")
super().m()
class c(a):
def m(self):
print("m of c called")
super().m()
class d(b,c):
def m(self):
print("m of d called")
super().m()
輸出如下:
m of d called
m of b called
m of c called
m of a called
在當前類中沒有init方法,木有覆蓋的情況下,多重繼承搜尋策略(參考:python3 多繼承搜尋__init__方法的兩種策略):
class a(object):
def __init__(self):
print('a')
class b(object):
def __init__(self):
print('b')
class c(a):
def __init__(self):
print('c')
class d(b):
def __init__(self):
print('d')
class e(c, d):
pass
這種情形下,python3搜尋__init__方法的順序是 e->c->a->d->b
這種情況下python3搜尋__init__方法的順序是 e->c->d->a
在當前的類中,有init方法,在該init的方法中,有super().init()方法(只能呼叫第乙個父類的方法),結論也是類似:
class a(object):
def __init__(self):
print('a')
class b(object):
def __init__(self):
print('b')
class c(a):
def __init__(self):
print('c')
class d(b):
def __init__(self):
print('d')
class e(c, d):
def __init__(self):
print('e')
super().init()
知識摘抄過來,沒有實戰經驗
# base classes
class a:
def __init__(self, a1, a2, **kwargs):
super().__init__(**kwargs)
self.a1 = a1
self.a2 = a2
def funa(self):
print("i'm funa")
class b:
def __init__(self, b1, **kwargs):
super().__init__(**kwargs)
self.b1 = b1
def funb(self):
print("i'm funb")
class c:
def __init__(self, c1, c2, c3, **kwargs):
super().__init__(**kwargs)
self.c1 = c1
self.c2 = c2
self.c3 = c3
def func(self):
print("i'm func")
# derived classes
class x(b, a, c):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class y(a, b):
def __init__(self, **kwargs):
super().__init__(**kwargs)
class a(object):
def __init__(self, a1,a2):
# super(classname, self).__init__()
self.a1 = a1
self.a2 = a2
def funa(self):
print("i'm funa")
class b(object):
def __init__(self, b1):
# super(classname, self).__init__()
self.b1 = b1
def funb(self):
print("i'm funb")
class c(a, b):
def __init__(self, a1, a2, b1):
a.__init__(self, a1, a2)
b.__init__(self, b1)
c = c(1, 2, 3)
dir(c)
python 多重繼承
python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。對經典類和新式類來說,屬性的查詢順序是不同的。現在我們分別看一下經典類和新式類兩種不同的表現 經典類 usr bin pyth...
Python多重繼承
class printa namea printa def set value self,a self.a a def set namea self,namea printa.namea namea def info self print printa s,s printa.namea,self.a...
python多重繼承
class d object pass class c d pass class b d pass class a b,c pass mro method resolution order 方法解析順序 為了解決多繼承問題 在inspect檔案中 採用aov圖,每次輸出乙個入度為零的點 相當於沒有人...