4

私はプログラミングにまったく慣れておらず、まだ自分のロープを学んでいます。この質問が初歩的すぎる場合はお詫び申し上げます。

質問を明確にするのは少し難しいと思うので、達成したいことの例を次に示します。aがクラスXのインスタンスであり、属性a1、a2、a3、b1、b2、b3、c1を持つことになっているとします。 、c2およびc3。使いやすさのために、a1からa3、b1からb3、c1からc3を、Xの下にネストされた独自のクラスA、B、Cに入れたいと思います。そうするための正しい構文は何でしょうか?

 class X:
    def __init__ (self, name, A, B, C):
        self.name = name
        self.A = A
        self.B = B
        self.C = C
    class A (X):
       def _init_ (self, name, a1, a2, a3):
           self.name = name
           self.a1 = a1
           self.a2 = a2
           self.a3 = a3
    class B (x):
       def _init_ (self, name, b1, b2, b3):
           self.name = name
           self.b1 = a1
           self.b2 = a2
           self.b3 = a3
    class C (X):
       def _init_ (self, name, c1, c2, c3):
           self.name = name
           self.c1 = a1
           self.c2 = a2
           self.c3 = a3

これは完全に当​​て推量に基づいて構築されているので、99.9%間違いだと確信していますが、正しくするために次に何をすべきかわかりません。「ネストされたクラス」の回答を検索してみましたが、見つけた回答では自分の立場が明確になりませんでした。

Pythonのネストされたクラスの適切な構文を説明してください。

ご協力いただきありがとうございます。この基本的な質問についてお詫び申し上げます。

編集:私のコードには、今修正した重大なタイプミスがいくつかありました。ご不便をおかけして申し訳ございません。

4

2 に答える 2

3

ネストされたクラスは、その定義が別のスコープ内に存在するクラスです。それらは通常、Python ではそれほど有用ではありません。ただし、必要に応じて、複数のクラスの属性から 1 つのクラスの属性を派生させることは可能です。主な 2 つの方法は、ミックスイン / 多重継承合成です。

ミックスインのアプローチは次のようになります。

class A(object):
    def __init__(self, a=None, *args, **kwargs):
        self.a = a
        super(A, self).__init__(*args, **kwargs)

class B(object):
    def __init__(self, b=None, *args, **kwargs):
        self.b = b
        super(B, self).__init__(*args, **kwargs)

class X(A, B):
    def __init__(self, *args, **kwargs):
        super(X, self).__init__(*args, **kwargs)

x = X(a='foo', b='bar')
print x.a, x.b
  • Xの両方の属性を持つように、両方から継承します。ABclass X(A, B)

  • それぞれがパラメーターとして__init__受け入れます。*args, **kwargs私たちのsuper()呼び出しはとXの初期化子に名前付きパラメータを渡すため、他の初期化子のパラメータを受け入れる (そして無視する) ことができるようにする必要があります。つまり、 と の両方を渡しますが、 のみを使用します。ABabA.__init__a

  • Python の継承を理解するには、この記事を読むことsuper()が不可欠です。

ただし、多重継承は過去の単純な例を管理するのが難しい場合があるため、代わりに構成を使用することをお勧めします。

class A(object):
    def __init__(self, a):
        self.a = a

class B(object):
    def __init__(self, b):
        self.b = b

class X(object):
    def __init__(self, a, b):
        self.A = A(a)
        self.B = B(b)

x = X('foo', 'bar')
print x.A.a, x.B.b

super()これにより、呼び出しやイニシャライザーでの特別なパラメーター処理が不要になり、より明確になっていることがわかります。ここでは 2 つのパラメーターを取り、関連するクラスを内部で構築してXインスタンスにアタッチします。これにより、属性の検索が少し厄介になりますが、それを簡単にする方法があります。

class X(object):
    # <etc>
    @property
    def a(self):
        return self.A.a

各プロパティを手作業でコーディングする代わりに、オーバーライド__getattr__していくつかの動的ルックアップを実行することもできます。

class X(object):
    # <etc>
    def __getattr__(self, item):
        for component in (getattr(self, c) for c in ['A', 'B']):
            if hasattr(component, item):
                return getattr(component, item)

別のオプションは、構成されたインスタンスを自分で渡すことです。

class X(object):
    def __init__(self, A, B):
        self.A = A
        self.B = B

x = X(A('foo'), B('bar'))
print x.A.a, x.B.b

これにより、インターフェイス以外のことをX知る必要がなくなります。これにより、カプセル化が容易になります。必要に応じて、独自のモジュールに貼り付けることができます。便宜上、ファクトリ関数を使用することもできます。ABAB

def make_X(a, b):
    return X(
        A(a), 
        B(b)
    )
于 2012-05-22T06:24:56.843 に答える
1

あなたは継承を探しています。

また、Pythonでは大文字と小文字が区別されることを見逃していることに気付きました。これは、aAが同じ変数ではないことを意味します

 class X:
    def __init__ (self, name, a, b, c):
        self.name = name
        self.a = a

class A (X):
   def _init_ (self, name, a1, a2, a3):
       self.name = name
       self.a1 = a1
       self.a2 = a2
       self.a3 = a3

class B (A):
   def _init_ (self, name, a1, a2, a3):
       self.name = name
       self.b1 = a1
       self.b2 = a2
       self.b3 = a3

class C (A):
   def _init_ (self, name, a1, a2, a3):
       self.name = name
       self.c1 = a1
       self.c2 = a2
       self.c3 = a3

お役に立てれば

于 2012-05-22T05:10:43.320 に答える