<!-- TOC -->python
<!-- /TOC -->this
Py 2.x 和 Py 3.x 中有一个很大的区别就是类,不管是类的定义仍是类的继承。
Py 3.x 中类的继承能够直接使用 super() 关键字代替原来的 super(Class, self)。code
那么 super() 究竟是依据什么来继承的呢?继承
super()函数根据传进去的两个参数具体做用以下:it
经过第一参数传进去的类名肯定当前在MRO中的哪一个位置。MRO(Method Resolution Order)
经过第二个参数传进去的self,肯定当前的MRO列表。
class A(object): def name(self): print('name is xiaoming') # super(A, self).name() class B(object): def name(self): print('name is cat') class C(A, B): def name(self): print('name is wang') super(C, self).name() if __name__ == '__main__': c = C() print(c.__class__.__mro__) c.name()
返回结果是:io
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) name is wang name is xiaoming
若是把注释去掉的结果是:class
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>) name is wang name is xiaoming name is cat
再看一个例子:module
class Base(object): def func_1(self): print('this is base') class A(Base): def func_1(self): super().func_1() print('this is A') class B(Base): def func_1(self): super().func_1() print('this is B') class C(A, B): def func_1(self): super().func_1() print('this is c') print(C.mro()) C().func_1() print(help(C))
返回结果:object
Help on class C in module __main__: class C(A, B) | Method resolution order: | C | A | B
“从左到到右”的意思,C继承关系最近的是A, 而后是B,最后是上层BASE。
调用方法时的入栈顺序是 C A B Base,
出栈顺序是Base B A C,
class Base(object): def __init__(self): print("Base created") class ChildA(Base): def __init__(self): Base.__init__(self) class ChildB(Base): def __init__(self): # super(ChildB, self).__init__() # 或者更简单的写法 # super().__init__() # 若是不用super写法就要这样写 print("self=", self) # <__main__.ChildB object at 0x000001EA8CD085F8> mro = type(self).mro() print(mro) # [<class '__main__.ChildB'>, <class '__main__.Base'>, <class 'object'>] for next_class in mro[mro.index(ChildB) + 1:]: print(next_class) # <class '__main__.Base'> if hasattr(next_class, '__init__'): next_class.__init__(self) break print(ChildA()) print("#" * 10) print(ChildB())
看下面的代码:
class Base(object): def __init__(self): print("Base created") class ChildA(Base): def __init__(self): print("ChildA init...") Base.__init__(self) class ChildB(Base): def __init__(self): print("ChildB init..") # super(ChildB, self).__init__() # 或者更简单的写法 super().__init__() if __name__ == "__main__": print(ChildA()) print("#" * 10) print(ChildB())
返回值:
ChildA init... Base created <__main__.ChildA object at 0x000001D089FE85F8> ########## ChildB init.. Base created <__main__.ChildB object at 0x000001D089FE85F8>
能够看到结果是同样的,那么 Base.__init__(self)
和 super().__init__()
有什么区别呢?
请看这个例子:
class Base(object): def __init__(self): print("Base created") class UserDependency(Base): def __init__(self): print("UserDependency init...") super().__init__() class ChildA(Base): def __init__(self): print("ChildA init...") Base.__init__(self) class ChildB(Base): def __init__(self): print("ChildB init..") # super(ChildB, self).__init__() # 或者更简单的写法 super().__init__() class UserA(ChildA, UserDependency): def __init__(self): print("UserA init...") super(UserA, self).__init__() class UserB(ChildB, UserDependency): def __init__(self): print("UserB init...") super(UserB, self).__init__() if __name__ == "__main__": print(UserA()) print("#" * 10) print(UserB())
返回结果:
UserA init... ChildA init... Base created <__main__.UserA object at 0x0000019295A38B00> ########## UserB init... ChildB init.. UserDependency init... Base created <__main__.UserB object at 0x0000019295A38B00>
这里咱们看到了区别,在多重继承中,没有使用super方法的类,没有调用UserDenpendency方法