1. 多继承以及MRO顺序
1.1 单独调用父类的方法
# -*- encoding=utf-8 -*- 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结束被调用") s = Son1("douzi", 23) s2 = Son2("douzi2", "男") print("="*20) s3 = Grandson("douzi3", 24, "男")
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
====================
Grandson的init开始被调用
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用-
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Grandson的init结束被调用
上述的操作及其费资源,比如网络编程时候,parent要创建一个socket,多个子类会创建多个socket,费资源。
1.2 C3算法,一套确定每个类只调用一次的算法(className.__mro__输出调用顺序)
所以,要把父类,改成super().__init__() ==> Parent只调用一次
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__(self, 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结束被调用") s = Son1("douzi", 23) s2 = Son2("douzi2", "男") print("="*20) s3 = Grandson("douzi3", 24, "男")
Son1的init开始被调用
parent的init开始被调用
parent的init结束被调用
Son1的init结束被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
====================
Grandson的init开始被调用
Son1的init开始被调用
Son2的init开始背调用
parent的init开始被调用
parent的init结束被调用
Son2的init结束被调用
Son1的init结束被调用
Grandson的init结束被调用
MRO属性
super()默认拿着自己的类名到MRO输出中找,找到匹配项的下一个的__init__执行
print(Grandson.__mro__)
(<class '__main__.Grandson'>, <class '__main__.Son1'>, <class '__main__.Son2'>, <class '__main__.Parent'>, <class 'object'>)
1.3 为避免多继承报错,使用不定参数: *args, **kwargs
def test1(a, b, *args, **kwargs): print(a) print(b) print(args) print(kwargs) test2(a, b, args, kwargs) print('-'*10) test2(a, b, *args, **kwargs) # 相当于 test2(11,22,33,44,55, name="douzi", age=18) def test2(a, b, *args, **kwargs): print('----------') print(a) print(b) print(args) print(kwargs) test1(11, 22, 33, 44, 55, name="douzi", age=18)