0

次のコードを検討してください。

class A(object):
    def __init__(self):
        print("A.__init__")
        super(A, self).__init__()          # 1
        print("A.__init__ finished")

class B(A):
    def __init__(self):
        print("B.__init__")
        super(B, self).__init__()          # 2
        print("B.__init__ finished")

class C(A):
    def __init__(self):
        print("C.__init__")
        super(C, self).__init__()
        print("C.__init__ finished")

class D(B, C):
    def __init__(self):
        print("D.__init__")
        print("Initializing B")
        B.__init__(self)                   # 3
        print("B initialized")
        print("Initializing C")
        C.__init__(self)                   # 4
        print("C initialized")
        print("D.__init__ finished")

D()

# D.__init__
# Initializing B
# B.__init__
# C.__init__
# A.__init__
# A.__init__ finished
# C.__init__ finished
# B.__init__ finished
# B initialized
# Initializing C
# C.__init__
# A.__init__
# A.__init__ finished
# C.__init__ finished
# C initialized
# D.__init__ finished

私が理解している限り、アルゴリズムは次のとおりです。

D.__init__ at (3) -> B.__init__ -> 
-> super().__init__ -> (super of self.__class__).__init__ ->
-> C.__init__ (# why C?) -> super().__init__ -> 
-> A.__init__

D.__init__ at (4) -> C.__init__ ->
-> super().__init__ -> 
-> A.__init__

実際には 3 つの
質問がありsuper().__init__()ます。2.この場合、 コールと2 回を回避するにはどうすればよいですか? 2.1 現在のクラスが継承するすべてのクラスを初期化する正しい方法は?B.__init__C.__init__selfD
C.__init__A.__init__

4

1 に答える 1

5

Q: self が D のインスタンスであるのに、(2 で) 呼び出しを呼び出すのはなぜですか?super().__init__()B.__init__C.__init__

電話すると

super(X, self).__init__

Python はMRO self.__class__.mro()を検索します。次に、MRO 内の Xの次の__init__クラスから呼び出します。

self が のインスタンスの場合Dself.__class__.mro()is[D, B, C, A]です。を呼び出しsuper(B, self).__init__()ますC.__init__(self)


Q:現在のクラスが継承するすべてのクラスを初期化する正しい方法は何ですか?

スーパーインD.__init__も使用します。

class D(B, C):
    def __init__(self):
        print("D.__init__")
        super(D, self).__init__()
        print("D.__init__ finished")
于 2012-09-17T10:45:44.720 に答える