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