2016-09-16 10 views
3

これは動作しません:のpython:ネストされたクラス:アクセス外側のクラスのクラスメンバー

class A: 
    a1 = 4 

    class B: 
    b1 = A.a1 # Fails 
    b2 = 6 

    class C: 
    c1 = A.B.b2 # Fails 

それを解決するために、任意の非暗号のような方法はありますか?私はAからBとCを取ることができることを知っていますが、私はそれらを埋め込んでおきたいと思います。また、クラスメンバーがいない方が、コンストラクターの引数としてネストされたクラスに簡単に渡すことができるようになると簡単だと思いますが、クラスメンバーの皆さんはここで何か似たようなことをする方法がわかりません。私はまた、この使用法はクラスを名前空間として使用することを覚えていますが、クラスではなくモジュールを使用して解決する必要があるスレッドを読みましたが、クラスの上にクラスデータがある私の共有クラスその中で。

UPDATE:私はクラスメンバーを共有するための本当に汚い方法を見つけ、私はまだ満足していない:

global_tal = None          
global_tal2 = None         


class A:            
    a1 = 4           
    global global_tal         
    global_tal = a1         

    class B:           
     global global_tal        
     b0 = global_tal # it works     
     # Desired way: b1 = A.a1 # Fails    
     b2 = 6          

    global global_tal2        
    global_tal2 = B         

    class C:           
     global global_tal2       
     c1 = global_tal2.b2 # it works    
     # Desired way: c1 = A.B.b2 # Fails   
     pass           

はUPDATE 2:きれいな方法(私見)。 dhkeに感謝します。

class _SharedReferences:          
     ref1 = None            
     ref2 = None            


class A(_SharedReferences):         
    a1 = 4             
    _SharedReferences.ref1 = a1        

    class B:             
     b0 = _SharedReferences.ref1 # it works    
     # Desired way: b1 = A.a1 # Fails     
     b2 = 6            

    _SharedReferences.ref1 = B        

    class C:             
     c1 = _SharedReferences.ref1.b2 # it works   
     # Desired way: c1 = A.B.b2 # Fails     
     pass             
+0

"簡単な"方法は、A、B、およびCのすべてが継承するパラメータクラスです。 – dhke

+1

あなたの言うことをよく分かりません。上に別のレベルの継承を追加する? – user2761220

+0

以下を参照してください。基本的に 'A(Param)'と 'B(Param)'を持っているか、パラメータに別の名前が必要な場合は 'A'ではなく' Param'からクラス変数を引きます。 – dhke

答えて

1

これには2つの理由があります。 1つは、NameErrorというBA.a1にアクセスしようとすると、Aは準備ができていないということです。

この問題を解決するには、サブクラスを使用します。以下は動作します:

class A: 
    a1 = 4 

class _A(A): 

    class B: 
    b1 = A.a1 # Fails 
    b2 = 6 

は、しかし、まだAとして動作しませんA.B.b2Cにアクセスする一切の属性Bを持っていません。その上にAttributeErrorが表示されます。

1

あなたはAが完全に定義されるまでBの定義を延期し、AA.Bの両方が定義されるまでCを延期することがあります。

class A: 
    a1 = 4 

class B: 
    b1 = A.a1 
    b2 = 6 
A.B = B 
del B 

class C: 
    c1 = A.B.b2 
A.C = C 
del C 

assert A.B.b1 == 4 
assert A.C.c1 == 6 

また、あなたはBの定義の外B.b1を定義することができます。

class A: 
    a1 = 4 

    class B: 
    pass 
    B.b1 = a1 
    B.b2 = 6 

    class C: 
    pass 
    C.c1 = B.b2 

assert A.B.b1 == 4 
assert A.C.c1 == 6 
0

1つのトリックはそれからパラメータクラスに共通のパラメータを入れて、継承することです:

class Params: 
    p = 4 

class A(Params): 
    # A has p 
    class B(Params): 
     # B has p 
     pass 

    class C(Params): 
     # C has p 
     pass 

または、内部クラスに異なる名前のパラメータが必要な場合:

class A(Params): 
    # A has p 
    class B: 
     b = Params.p 

    class C: 
     c = Params.p 

これにより、作成後にクラスにモンキーパッチを適用する必要がなくなります。

関連する問題