私は自分自身がダイヤモンド継承の奇妙な状況にあることを知っています。さらに悪いことに、ダイヤモンドの中間のクラスがメンバを共有しています。下に私の問題を強調するコードの断片を示しました。pythonとsuperで同じメンバでクラスを継承する
出力
z : None
に問題を与え、私は組み込み関数super
class A(object):
pass
class B(A):
def __init__(self, z=None, **kwargs):
self.z = z
super(B, self).__init__(**kwargs)
# super(B, self).__init__(z=z, **kwargs)
class C(A):
def __init__(self, z=None, **kwargs):
self.z = z
super(C, self).__init__(**kwargs)
class D(B, C):
pass
d = D(z='y')
for arg, value in d.__dict__.iteritems():
print arg, ':', value
のためのPythonドキュメントサイトにリンクされている私はhttp://rhettinger.wordpress.com/2011/05/26/super-considered-super/から学んだライティングのクラスで使用する方法関数の一致の署名がクラスCのinit呼び出しからz引数を取り除くことを保証するためにキーワード引数を使用する方法です。引数を強制的にkwargsに追加することができますが(コメント付きコードを参照)、これはB型のオブジェクトをインスタンス化することができません。これはパラメータを取らないオブジェクトのinitを呼び出すことになります。これは、以下のオブジェクトのいずれかをインスタンス化する際に無効な引数を入れないためです。
また、変数を設定する前にスーパーがあると、最高レベルのオブジェクトが下位レベルを上書きするため、問題が修正されています。しかし、実際の "設定"はすべて低レベルのクラスで実行され、高レベルのクラスは継承の連鎖を設定する値を渡すので、私のコードは大まかに構築されています。親コールにどこに適合するかについてのガイドラインはありますか?
任意のアイデアStackoverflow?
ありがとう
p.s.これはちょうど「協同組合」の悪いデザインですか?協同組合のクラスとは何ですか?従うべき規則やガイドラインはありますか?
編集:
StackOverflowのは、私は自分の質問に答えることはできませんが、私は解決策を考え出しました。
私は、協調クラス間で共有メンバーが存在するはずはないと思います。これまでに、互いに独立した2つのクラスがある場合(つまり、ある種の関係です)、メンバーを共有する場合、継承関係に抽象レベルを追加する必要があります。
共有メンバーを取り出し、共有ベースクラスから継承し、ダイヤモンドのクラスによってから継承されている別のクラスに入れなければなりません。
以下は修正されたコードです。 OP内のリンクを踏まえて、私は(私が推測ここで最もように)私は間違った用語を使用する場合、私は謝罪ので、私は正式なプログラミング教育を受けていない指摘しなければならないルートベースクラス
を導入しました。
class Root(object):
pass
class A(Root):
pass
class HasAZ(Root):
def __init__(self, z=None, **kwargs):
self.z = z
super(HasAZ, self).__init__(**kwargs)
class B(HasAZ, A):
pass
class C(HasAZ, A):
pass
class D(B, C):
pass
d = D(z='y')
for arg, value in d.__dict__.iteritems():
print arg, ':', value
多重継承を使用しないでください彼らがメンバーを共有しているという事実。彼らがメンバーを共有している場合は、他の何かを共有する必要があります。メンバーを連れて共通のクラスに引き出すことはできませんか? –
ありがとう、それは私が最後にしたものです。私は明らかに私のオブジェクト指向の思考プロセスに取り組む必要があります – scruffyDog
私はそれが最高のためだと思っています=) –