Python学習:super()

2134 ワード

参照先:https://www.jianshu.com/p/45619cf50aa7
super()はPythonでクラスの継承によく用いられ,直接呼び出し継承よりも親が繰り返し呼び出されないことを保証するためにsuper()を用いる.
単純な呼び出し親の場合:
class parent:
    def fun1(self,message):
        print(message)
class child(parent):
    def fun2(self,message):
        parent.fun1(self,message)

>>> child().fun2('hello')
hello

上記の例では、親の名前が変更された場合、子の名前も変更されます.この問題を回避するためにsuper()で解決できる
class parent:
    def fun1(self,message):
        print(message)
class child(parent):
    def fun2(self,message):
        super(child,self).fun1(message)

>>> child().fun2('hello')
hello

上記の2つの例ではsuper(child,self)である.fun 1(message)とparent.fun 1(self,message)の表現は一致するが、マルチ継承に関連する場合、2つの呼び出し方式に差が生じる.
class A:
    def __init__(self):
        print('Enter A')
        print('Leave A')
class B(A):
    def __init__(self):
        print('Enter B')
        A.__init__(self)
        print('Leave B')
class C(A):
    def __init__(self):
        print('Enter C')
        A.__init__(self)
        print('Leave C')
class D(B,C):
    def __init__(self):
        print ('Enter D')
        B.__init__(self)
        C.__init__(self)
        print('Leave D')
        
>>> D()
Enter D
Enter B
Enter A
Leave A
Leave B
Enter C
Enter A
Leave A
Leave C
Leave D

下はsuper()の場合で、superメカニズムでは共通の親が一度だけ実行され、MRO(Method Resolution Order)に従って実行されることを保証できます.
class A:
    def __init__(self):
        print('Enter A')
        print('Leave A')
class B(A):
    def __init__(self):
        print('Enter B')
        super(B,self).__init__()
        print('Leave B')
class C(A):
    def __init__(self):
        print('Enter C')
        super(C,self).__init__()
        print('Leave C')
class D(B,C):
    def __init__(self):
        print ('Enter D')
        super(D,self).__init__()
        print('Leave D')
        
>>> D()
Enter D
Enter B
Enter C
Enter A
Leave A
Leave C
Leave B
Leave D