647 字
3 分钟
第12章-类继承
第12章-类继承
[toc]
super函数
Py 2.x 和 Py 3.x 中有一个很大的区别就是类,无论是类的定义还是类的继承。 Py 3.x 中类的继承可以直接使用 super() 关键字代替原来的 super(Class, self)。
那么 super() 到底是依据什么来继承的呢?
super()函数根据传进去的两个参数具体作用如下:
通过第一参数传进去的类名确定当前在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()返回结果是:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)name is wangname is xiaoming如果把注释去掉的结果是:
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)name is wangname is xiaomingname is cat再看一个例子:
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))返回结果:
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方法`**