mro了解
def super(cls, inst):
"""
:param cls: 类对象
:param inst: 实例
:return:
"""
mro = inst.__class__.mro()
return mro[mro.index(cls) + 1]
其中,cls 代表类,inst 代表实例,上面的代码做了两件事:
- 获取 inst 的 MRO 列表
- 查找 cls 在当前 MRO 列表中的 index, 并返回它的下一个类,即 mro[index + 1]
当使用 super(cls, inst) 时,Python 会在 inst 的 MRO 列表上搜索 cls 的下一个类。
super学习
-
代码示例
class Base: def __init__(self): print("enter Base") print("leave Base") class A(Base): def __init__(self): print("enter A") super(A,self).__init__() print("leave A") class B(Base): def __init__(self): print("enter B") super(B,self).__init__() print("leave B") class C(A,B): def __init__(self): print("enter C") super(C,self).__init__() print("leave C") print(C.mro()) c=C()
-
运行结果
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Base'>, <class 'object'>] enter C enter A enter B enter Base leave Base leave B leave A leave C
-
分析
C对象初始化时调用super,在mro列表中进入A对象初始化,此时super(A,self).__init__()中self为C实例c,参考上述mro实现,返回B类,进行B对象的初始化,再进行Base初始化
思考
-
代码示例1
class Base1: def __init__(self): print("enter Base1") # super().__init__() print("leave Base1") class Base2: def __init__(self): print("enter Base2") print("leave Base2") class A(Base1): def __init__(self): print("enter A") super().__init__() print("leave A") class B(Base2): def __init__(self): print("enter B") super().__init__() print("leave B") class C(A, B): def __init__(self): print("enter C") super().__init__() print("leave C") print(C.mro()) c = C()
-
运行结果
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.Base1'>, <class '__main__.B'>, <class '__main__.Base2'>, <class 'object'>] enter C enter A enter Base1 leave Base1 leave A leave C
-
此处mro包含Base1、Base2,但未初始化Base2。因为在初始化Base1时,并未存在super即不会寻找mro列表中下一项。取消Base1super注释后,可按照mro初始化
-
修改后运行结果
[<class '__main__.C'>, <class '__main__.A'>, <class '__main__.Base1'>, <class '__main__.B'>, <class '__main__.Base2'>, <class 'object'>] enter C enter A enter Base1 enter B enter Base2 leave Base2 leave B leave Base1 leave A leave C
super多继承问题
- 优雅的多继承尝试
运行结果class AAA: def __init__(self, a, b, c): super(AAA, self).__init__(b, c) self.a = a class BBB: def __init__(self, b, c): super(BBB, self).__init__(c) self.b = b class CCC: def __init__(self, c): self.c = c class Test(AAA, BBB, CCC): def __init__(self, a, b, c): super(Test, self).__init__(a, b, c) print(Test.mro()) test = Test(1, 2, 3) print(test.__dict__)
[<class '__main__.Test'>, <class '__main__.AAA'>, <class '__main__.BBB'>, <class '__main__.CCC'>, <class 'object'>] {'c': 3, 'b': 2, 'a': 1}