22

重複の可能性:
Super は多重継承を処理できますか?

パイソン継承?クラス構造 (以下) があり、子クラス__init__が両方の親の を呼び出すようにします。これは「超」方法で行うことが可能ですか、それとも単にひどい考えですか?

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def _init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        ## call __init__ of Parent1
        ## call __init__ of Parent2
        ## super(Child, self).__init__()
4

3 に答える 3

42

の考え方は、両方のスーパークラスのメソッドを個別super()に呼び出す必要がないということです。正しく使用すれば、それを処理します。Raymond Hettinger の「Python の super() はスーパーと見なされます!」を参照してください。説明のために。__init__()super()

とはいえ、for コンストラクター呼び出しの欠点がsuper()利点を上回っていることがよくあります。たとえば、すべてのコンストラクターが追加の**kwargs引数を提供する必要がある、すべてのクラスが連携する必要がある、連携しない外部クラスがラッパーを必要とする、各コンストラクターのパラメーター名がすべてのクラスで一意になるように注意する必要がある、などです。

そのため、多くの場合、コンストラクター呼び出しで呼び出したい基本クラス メソッドを明示的に指定する方が簡単だと思います。

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)

super()ただし、のように、プロトタイプが保証されている関数には使用し__getattr__()ます。これらの場合、デメリットはありません。

于 2011-11-04T17:04:42.000 に答える
26

呼び出しによる呼び出しsuperは、すべての親を呼び出すのではなく、MRO チェーンの次の関数を呼び出します。superこれが適切に機能するためには、すべての で次を使用する必要があります__init__

class Parent1(object):
    def __init__(self):
        super(Parent1, self).__init__()
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        super(Parent2, self).__init__()
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        super(Child, self).__init__()

super()Python 3 では、代わりに を使用できますsuper(type, instance)

于 2011-11-04T17:06:23.337 に答える
13

次のように直接呼び出すことができますParent.__init__(self)

class Parent1(object):
    def __init__(self):
        self.var1 = 1

class Parent2(object):
    def __init__(self):
        self.var2 = 2

class Child(Parent1, Parent2):
    def __init__(self):
        Parent1.__init__(self)
        Parent2.__init__(self)
        print(self.var1, self.var2)
于 2011-11-04T17:05:52.803 に答える