superを使用して親を初期化する


親を継承する子がある場合は、superの組み込み関数を使用して、ダイヤモンドレイヤの共通の親のみを呼び出すことができます.
ダイヤモンド階層とは?
  • 複数の親を継承する場合、その親に共通の親がある場合、そのクラスの階層はダイヤモンド状になり、ダイヤモンド層と呼ばれる.
  • 次のコードを使用すると、ダイヤモンド形状のクラス構造を再作成するのではなく、superを使用して親を初期化します.
    これにより、ダイヤモンド頂点のMyBaseClassに到達すると、MyBaseClass.__init__は一度だけ呼び出され、中間が覆われ、発生した問題は消失する.
    ちょうげんもんだい
    (例)以下の例は、Python符号化技術(リビジョン2版、ブラウザ)から来ている.
    # 부모 클래스
    class MyBaseClass:
    	def __init__(self, value):
        	self.value = value
            
    # 자식 클래스
    class TimesSeven(MyBaseClass):
    	def __init__(self, value):
        	MyBaseClass.__init__(self, value)
            self.value *= 7
    
    # 자식 클래스
    class PlusNine(MyBaseClass):
    	def __init__(self, value):
        	MyBaseClass.__init__(self, value)
            self.value += 9
    以下に示すように、TimesSevenとPlusNineを継承するサブクラスが定義されている場合、MyBaseClassはダイヤモンド層の一番上に位置します.
    この場合、2番目の親の作成者PlusNine.__init__(self, value)が呼び出されると、MyBaseClassが呼び出される.init(self,value)の再呼び出しに伴いself.値は5に戻ります.
    これは予想された結果ではないので、間違いを見つけるのは難しい.
    class ThisWay(TimesSeven, PlusNine):
    	def __init__(self, value):
    		TimesSeven.__init__(self, value)
    		PlusNine.__init__(self, value)
            
    print(ThisWay(5).value)  # (5 * 7) + 9 = 44가 아닌 14가 나옴
    したがって、superは、ダイヤモンド層の共通の親のみが呼び出されることを保証するために、以下のように使用することができる.
    class TimesSeven(MyBaseClass):
    	def __init__(self, value):
        	super().__init__(self, value)
            self.value *= 7
    
    class PlusNine(MyBaseClass):
    	def __init__(self, value):
        	super().__init__(self, value)
            self.value += 9
    
    # TimesSeven과 PlusNine을 상속 받은 클래스
    class GoodWay(TimesSeven, PlusNine):
    	def __init__(self, value):
    		super().__init__(self, value)
    現在はMyBaseClass.__init__が1回しか呼び出されておらず、過度な照明による問題は発生しません.
    もう一度分析してみると、
  • 継承ダイヤモンドの頂点に達すると、各初期化方法は、各クラスの__init__呼び出し順序の逆順序に従って動作する(呼び出しは逆順序).
    -すなわち, , , 順に操作します.