父、子类的执行顺序
当子类继承父类,子类和父类中有相同的函数,那么先执行哪个呢?
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()