我正在处理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)
属性装饰器是一种巧妙的方式,允许我在必要时引入回调而不改变类接口。但是,在第三个或第四个变量之后,它会使代码重复一次。
有没有办法将这种模式重构为以下内容:
class A(object):
def __init__(self):
self.var = 0
enable_callback(self, 'var', 'var_callbacks')
答案 0 :(得分: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
答案 1 :(得分:2)
查看Python descriptor protocol。实质上,您可以定义一个处理属性的获取,设置和删除的类。因此,您可以定义一个描述符,用于在设置属性时运行回调。
描述符是常规类,可以参数化。所以你可以实现一个描述符,它将目标变量作为构造函数。如下所示:
class A(object):
var = CallbackDescriptor('var')
foo = CallbackDescriptor('foo')