0

Pythonのデコレータを理解し、それらを使用して、次の単純なパターンを使用していくつかのインスタンス変数にコールバックを追加しています。

class A(object):
    def __init__(self):
        self._var = 0
        self.var_callbacks = []

    @property
    def var(self):
        return self._var

    @var.setter
    def var(self, x):
        self._var = x
        for f in self.var_callbacks:
            f(x)

プロパティデコレータは、クラスインターフェイスを変更せずに、必要に応じてコールバックを導入できるようにするための優れた方法です。ただし、3番目または4番目の変数の後では、コードが少し繰り返されます。

このパターンを次のようなものにリファクタリングする方法はありますか?

class A(object):
    def __init__(self):
        self.var = 0
        enable_callback(self, 'var', 'var_callbacks')
4

2 に答える 2

3

クラスにプロパティを設定する必要があるため(記述子であるため)、enable_callback初期化子での呼び出しの使用は機能しません。

クラスデコレータを使用して、パターンからプロパティを設定できます。

def callback_properties(callbacks_attribute, *names):
    def create_callback_property(name):
        def getter(self):
            return getattr(self, '_' + name)
        def setter(self, value):
            setattr(self, '_' + name, value)
            for f in getattr(self, callbacks_attribute):
                f(value)
        return property(getter, setter)

    def add_callback_properties(cls):
        for name in names:
            setattr(cls, name, create_callback_property(name)

        return cls

    return add_callback_properties

次に、それを次のように使用します。

@add_callback_properties('var_callbacks', 'var1', 'var2')
class A(object):
    # everything else
于 2013-03-25T11:16:03.690 に答える
2

Python記述子プロトコルを見てください。基本的に、プロパティの取得、設定、および削除を処理するクラスを定義できます。したがって、属性の設定時にコールバックを実行する記述子を定義できます。

記述子は通常のクラスであり、パラメーター化できます。したがって、宛先変数をコンストラクターとする記述子を実装できます。次のようなもの:

class A(object):
    var = CallbackDescriptor('var')
    foo = CallbackDescriptor('foo')
于 2013-03-25T11:04:14.023 に答える