當子類繼承父類,子類和父類中有相同的函數,那麼先執行哪個呢?
class Animal():
def run(self):
print("動物會跑!")
class People(Animal):
def run(self):
print("人會跑!")
running = People()
running.run()
"""
Output:
人會跑!
"""
當有__init__()函數時呢?
#----------------父類中有__init__()------------------#
class Animal():
def __init__(self):
print("動物開始准備...")
def run(self):
print("動物會跑!")
class People(Animal):
def run(self):
print("人會跑!")
running = People()
running.run()
"""
Output:
動物開始准備...
人會跑!
"""
#----------------父子類都有__init__()------------------#
class Animal():
def __init__(self):
print("動物開始准備...")
def run(self):
print("動物會跑!")
class People(Animal):
def __init__(self):
print("人開始准備...")
def run(self):
print("人會跑!")
running = People()
running.run()
"""
Output:
人開始准備...
人會跑!
"""
可以看出,真是長江後浪推前浪,子類把父類淹沒在沙灘上.....
那麼當子類繼承了多個父類呢?這裡舉兩個爸爸的栗子吧。
class Animal1():
def __init__(self):
print("1開始准備...")
def run(self):
print("動物1會跑!")
class Animal2():
def __init__(self):
print("2開始准備...")
def run(self):
print("動物2會跑!")
class People(Animal1, Animal2):
pass # 為了清楚展示父類調用順序,子類就pass。
# 當然,如果子類還有輸出內容,還會優先輸出子類內容
"""
Output:
1開始准備...
動物1會跑!
"""
#---------------看個有趣的,注意run函數命名--------------#
class Animal1():
def __init__(self):
print("1開始准備...")
def run(self):
print("動物1會跑!")
class Animal2():
def __init__(self):
print("2開始准備...")
def run2(self):
print("動物2會跑!")
class People(Animal1, Animal2):
pass
"""
Output:
1開始准備...
動物2會跑!
"""
可以看出,子類People會根據繼承父類順序來執行,還是跟最開始的爸爸最親。就算調用了第②個爸爸的子函數,初始化的輸出還是選擇第①個爸爸。
看一下內部結構,classname.mro():每一個繼承父類的子類都有一個與方法解析順序相關的特殊屬性,__mro__裝著方法解析時,對象的查找順序,可以用這個屬性查看類的執行順序。可以看出,執行順序是由子類先出發→ 第一個父類 → 第二個父類 →...→ 第n個父類 → object。
mro通過元組方式存儲順序,可以通過訪問其下標值訪問類,以及類中的屬性!
People.mro()
"""
Output:
[__main__.People, __main__.Animal1, __main__.Animal2, object]
"""
People.__mro__[2].run2(People)
"""
Output:
動物2會跑!
"""
# mro的使用方式
# classname.mro()
# classname.__mro__
# classname().__class__.mro()