内容该要:
- MRO是什么?
- super主要解决什么问题?
- 代码实例
MRO:
method resolution order,主要用于在多继承时判断 方法、属性 的调用 路径;其中用到一种C3算法,这里不详细描述,以后再来总结。
super
- 调用父类,这个好理解;
- 解决多重继承问题,直接用类名调用父类方法在使用单继承的时候没问题,但是如果使用多继承,会涉及到查找顺序(MRO)、重复调用(钻石继承)等种种问题。super在多继承中按照MRO顺序逐个调用,在多继承中避免‘类名调用’带来的父类方法重复执行问题。
代码实例
1、类名.方法名调用
class Parent(object):
def __init__(self, name):
print('parent的init开始被调用')
self.name = name
print('parent的init结束被调用')
class Son1(Parent):
def __init__(self, name, age):
print('Son1的init开始被调用')
self.age = age
Parent.__init__(self, name)
print('Son1的init结束被调用')
class Son2(Parent):
def __init__(self, name, gender):
print('Son2的init开始被调用')
self.gender = gender
Parent.__init__(self, name) #
print('Son2的init结束被调用')
class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
print('Grandson的init开始被调用')
Son1.__init__(self, name, age)
Son2.__init__(self, name, gender)
print('Grandson的init结束被调用')
gs = Grandson('grandson', 12, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
# 执行结果
# Grandson的init开始被调用
# Son1的init开始被调用
# parent的init开始被调用
# parent的init结束被调用
# Son1的init结束被调用
# Son2的init开始被调用
# parent的init开始被调用
# parent的init结束被调用
# Son2的init结束被调用
# Grandson的init结束被调用
# 姓名: grandson
# 年龄: 12
# 性别: 男
2、super调用
class Parent(object):
def __init__(self, name, *args, **kwargs):
print('parent的init开始被调用')
self.name = name
print('parent的init结束被调用')
class Son1(Parent):
def __init__(self, name, age, *args, **kwargs):
print('Son1的init开始被调用')
self.age = age
super().__init__(name, *args, **kwargs)
print('Son1的init结束被调用')
class Son2(Parent):
def __init__(self, name, gender, *args, **kwargs):
print('Son2的init开始被调用')
self.gender = gender
super().__init__(name, *args, **kwargs)
print('Son2的init结束被调用')
class Grandson(Son1, Son2):
def __init__(self, name, age, gender):
print('Grandson的init开始被调用')
super().__init__(name, age, gender)
print('Grandson的init结束被调用')
print(Grandson.__mro__)
gs = Grandson('grandson', 12, '男')
print('姓名:', gs.name)
print('年龄:', gs.age)
print('性别:', gs.gender)
# 执行结果
# (<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
# Grandson的init开始被调用
# Son1的init开始被调用
# Son2的init开始被调用
# parent的init开始被调用
# parent的init结束被调用
# Son2的init结束被调用
# Son1的init结束被调用
# Grandson的init结束被调用
# 姓名: grandson
# 年龄: 12
# 性别: 男
对比两者运行结果可以看到‘类名.方法名’方式在运行过程中对父级方法造成了重复执行。
本篇内容参考了网上各位大佬的内容