2015-09-28 10 views
6

プロキシオブジェクトを返すクラスで何らかの記述子を作成したいと思います。プロキシオブジェクトは、インデックス付けされるとオブジェクトのメンバーを取得し、そのオブジェクトにインデックスを適用します。次に、合計を返します。今私は(cluster_signalが返す記述プロトコルを実装し、Pythonの記述子に私の配列を変更したPythonで適応可能な記述子

class CompartmentCluster(Cluster): 

    """ 
    Base class for cluster that manages evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence = ArraySumProxy([]) 

class BasicEvidenceTargetCluster(CompartmentCluster): 

    # This class variable creates a Python object named basic_in on the 
    # class, which implements the descriptor protocol. 

    def __init__(self, 
       *, 
       **kwargs): 
     super().__init__(**kwargs) 

     self.basic_in = np.zeros(self.size) 
     self.variable_evidence.arrays.append(self.basic_in) 

class ExplanationTargetCluster(CompartmentCluster): 

    """ 
    These clusters accept explanation evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.explanation_in = np.zeros(self.size) 
     self.variable_evidence.arrays.append(self.explanation_in) 

class X(BasicEvidenceTargetCluster, ExplanationTargetCluster): 
    pass 

:私はメンバ変数として実際の配列を持っていながら、

例えば、

class NDArrayProxy: 

    def __array__(self, dtype=None): 
     retval = self[:] 
     if dtype is not None: 
      return retval.astype(dtype, copy=False) 
     return retval 


class ArraySumProxy(NDArrayProxy): 

    def __init__(self, arrays): 
     self.arrays = arrays 

    @property 
    def shape(self): 
     return self.arrays[0].shape 

    def __getitem__(self, indices): 
     return np.sum([a[indices] 
         for a in self.arrays], 
         axis=0) 

このソリューションではうまく働きました数値配列):

class CompartmentCluster(Cluster): 

    """ 
    Base class for cluster that manages evidence. 
    """ 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence = ArraySumProxy([]) 

class BasicEvidenceTargetCluster(CompartmentCluster): 

    # This class variable creates a Python object named basic_in on the 
    # class, which implements the descriptor protocol. 

    basic_in = cluster_signal(text="Basic (in)", 
           color='bright orange') 

    def __init__(self, 
       *, 
       **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence.arrays.append(self.basic_in) 

class ExplanationTargetCluster(CompartmentCluster): 

    """ 
    These clusters accept explanation evidence. 
    """ 

    explanation_in = cluster_signal(text="Explanation (in)", 
            color='bright yellow') 

    def __init__(self, **kwargs): 
     super().__init__(**kwargs) 

     self.variable_evidence.arrays.append(self.explanation_in) 

class X(BasicEvidenceTargetCluster, ExplanationTargetCluster): 
    pass 

これは機能しませんappend文が記述子呼び出しの結果を追加するためです。私が必要とするのは、バインドされたメソッドまたは同様のプロキシのいずれかを追加することです。ソリューションを変更する最も良い方法は何ですか?つまり、変数basic_inexplanation_innumpyアレイでした。彼らは今ディスクリプタです。私はArraySumProxyのいくつかのバージョンを開発して、実際の配列を必要とするのではなく記述子で動作させたいと考えています。

+0

私はあなたの質問を完全に理解していません。以前にこれらのクラスをどのように使用していたか、変更された内容、変更後にどのように使用することができるのかを示すことができますか? – BrenBarn

+0

@brenbarn:要約。 –

+1

あなたの質問から、どのコードが常に使用されていて、どのコードが新しいかはわかりません。 –

答えて

1

ディスクリプタにアクセスすると、ディスクリプタが評価され、値が取得されます。あなたの記述子は常に同じオブジェクトを返すわけではないので(あなたはavioidできないと思いますが)、プロキシの初期化時にディスクリプタにアクセスしたくありません。

それをアクセスしないようにする最も簡単な方法は、単にその名前を覚えているので、代わりに:

self.variable_evidence.arrays.append(self.basic_in) 

あなたは:

self.variable_evidence.arrays.append((self, 'basic_in')) 

すると、当然のことながら、variable_evidenceを意識しなければなりませんそれにアクセスするにはgetattr(obj, name)してください。

もう1つの方法は、ディスクリプタが後で評価されるプロキシオブジェクトを返すようにすることです。あなたがゲッターを保存することができます...

EDIT

それとも...を私はあなたが何をしているかわかりませんが、それは良い味のためにあまりにも多くのプロキシのようになります。

self.variable_evidence.arrays.append(lambda: self.basic_in) 
+2

または単に 'lambda:self.basic_in'です。 – user2357112

+0

しかし、もう一度、記述子を取得するゲッターを持つプロキシー...すべてが必要ですか? – zvone

+0

@ user2357112はい、それは良いです:) – zvone

関連する問題