<!-- 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方法