6

プロキシ オブジェクトを返すクラスにある種の記述子を作成したいと考えています。プロキシ オブジェクトは、インデックスが作成されると、オブジェクトのメンバーを取得し、それらにインデックスを適用します。次に、合計を返します。

例えば、

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.

    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

これで、配列を Python 記述子に変更しました ( cluster_signalnumpy 配列を返す記述子プロトコルを実装します)。

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実際の配列を必要とするのではなく、記述子で動作するバージョンを開発したいと思います。

4

1 に答える 1

1

記述子にアクセスすると、それが評価され、値のみが取得されます。記述子は常に同じオブジェクトを返すとは限らないため (回避できないと思いますか?)、プロキシを初期化するときに記述子にアクセスしたくありません。

アクセスを避ける最も簡単な方法は、その名前を覚えておくことです。

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

あなたがやる:

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

もちろん、それをvariable_evidence認識しgetattr(obj, name)てアクセスする必要があります。

もう 1 つのオプションは、記述子が後で評価されるプロキシ オブジェクトを返すようにすることです。あなたが何をしているのかはわかりませんが、それはプロキシが多すぎて趣味が悪いかもしれません...

編集

または...ゲッターを保存できます:

self.variable_evidence.arrays.append(lambda: self.basic_in)
于 2015-12-23T23:44:36.683 に答える