繼承:單繼承:
#父類
class animal(object):
"""docstring for animal"""
def __init__(self, name):
self.name = name;
def run(self):
print(" is running".format(self.name))
def eat(self):
print(" is eatting".format(self.name))
#子類class dog(animal):
def __init__(self, name):
self.name = name;
# 子類呼叫父類中已有的方法
def animal_run(self):
print("\ncalling father's method:")
animal.run(self)
dog = dog("chichi")
dog.run()
dog.eat()
dog.animal_run()
執行結果:
[chichi] is running
[chichi] is eatting
calling father's method:
[chichi] is running
在單繼承的情況下,我們可以直接在子類中通過父類名.method()來呼叫父類的方法。
多繼承:
class a(object):
def __init__(self):
self.n = 'a'
print("i'm a, i am called from c")
def func(self):
print("self is in a.func".format(self))
self.n += 'a'
class b(a):
def __init__(self):
self.n = 'b'
print("i'm b, i am called from d")
def func(self):
print("self is in b.func".format(self))
super().func()
self.n += 'b'
class c(a):
def __init__(self):
self.n = 'c'
print("i'm c, i am called from b")
def func(self):
print("self is in c.func".format(self))
super().func()
self.n += 'c'
class d(b, c):
def __init__(self):
self.n = 'd'
super(d, self).func()
def func(self):
print("self is in d.func".format(self))
# super().func()
print(d.mro())
a.__init__(self)
print("calling by super():")
super(b,self).__init__()
self.n += 'd'
d = d()
d.func()
執行結果:
self is <__main__.d object at> in b.func
self is <__main__.d object at> in c.func
self is <__main__.d object at> in a.func
self is <__main__.d object at> in d.func
[, , , , ]
i'm a, i am called from c
calling by super():
i'm c, i am called from b
在多繼承中,我們也可以直接指明父類名並呼叫其中的方法,但這樣做需要我們直接寫出父類名,這在很多時候是很麻煩的事情。當該子類的父類名稱變化時,我們就需要修改很多地方的呼叫,所以在python2中引入了super()方法。
1. 我們在寫d的__init__()方法時,可以直接用如下**來呼叫其父類的初始化方法,然後在父類的基礎上繼續新增子類的個性化方法。
super(d,self).__init__()
2. 甚至我們可以完全不寫d的__init__(),當建立d的物件時,自動從父類繼承__init()__方法。
但在多繼承中,
1. 乙個子類有兩個父類時,應該呼叫哪個父類的方法呢?
2. 該例中,super是怎麼決定呼叫b還是c的init的呢?
3. 或者當直接的父類也沒有init函式,那是不是就直接繼續去找父類的父類呢?
python多繼承問題實質上是鑽石繼承問題(diamond inheritance):
對於該問題的解決方法是,規定乙個mro(method resolution order),所以在上例中,mro是d->b->c->a->object, 按該順序呼叫我們就能找到上面問題的答案。
1. 多繼承中,子類會按照mro呼叫排在自己下乙個的類中的方法。
2. 按照mro中的順序呼叫。
3. 當最初被呼叫的類沒有該方法時,python會按照mro的順序乙個乙個向前查詢,直到找到該方法。但需要注意的是,當d,b都沒有定義init時,呼叫的是c 而不是a 的init。
那麼mro順序是怎麼確定的呢?
一句話總結:父類總是出現在子類後,若有多個父類,其相對順序保持不變,在定義子類調參時,父類的順序就已經決定了mro順序。
這裡有一篇對mro順序的**,給出了很多有趣的例子。
Python中的多繼承
python和c 一樣,支援多繼承。概念雖然容易,但是困難的工作是如果子類呼叫乙個自身沒有定義的屬性,它是按照何種順序去到父類尋找呢,尤其是眾多父類中有多個都包含該同名屬性。class p1 object deffoo self print p1 foo class p2 object deffoo...
python中的多繼承
一 介紹 python同樣有限的支援多繼承形式。多繼承的類定義形如下例 class derivedclassname base1,base2,base3 需要注意圓括號中父類的順序,若是父類中有相同的方法名,而在子類使用時未指定,python從左至右搜尋 即方法在子類中未找到時,從左到右查詢父類中是...
Python中的多繼承
coding utf8 1.多繼承 子類有多個父類 class human def init self,self.defp self print 這是human的方法 class person def init self,name self.name name defp self print 這是p...