我正在尝试在描述符类中为魔术方法(__get__)添加额外的装饰器。
当我使用@property时,我可以做到这一点,但是当我使用描述符类时,我却不能做到。
我检查范围,因为我的对象集寄存器在总线上,并且某些寄存器只能采用特定范围的值:
import functools
def check_range(min, max):
def decorator(f):
@functools.wraps(f)
def wrap(self, value):
if value not in range(min, max+1):
return
return f(self, value)
return wrap
return decorator
这有效:
class Foo:
def __init__(self):
self.device.init_smth('my_object')
@property
def my_object(self):
return self.device.get_value('my_object')
@my_object.setter
@check_range(0,1)
def my_object(self, value):
self.device.set_value('my_object', value)
a = Foo()
print(a.my_object)
a.my_object = 1
print(a.my_object)
a.myobject = -1
在此示例中,所有操作均相同,但不调用check_range:
class Register:
def __init__(self, name, device):
self.name = name
device.init_smth(name)
def __get__(self, instance, owner):
return instance.device.get_value(self.name)
@check_range(0,1)
def __set__(self, instance, value):
instance.device.set_value(self.name, value)
class Foo:
def __init__(self):
self.my_object = Register('my_object', self.device)
a = Foo()
print(a.my_object)
a.my_object = 1
print(a.my_object)
a.myobject = -1
答案 0 :(得分:1)
我可能是错的,但很可能根本没有调用您的描述符,装饰器不是问题。描述符应该像
一样使用class Foo2:
my_object = Register('my_object', 'init_value')
-您正在像类属性一样定义它。如果您的类属性支持python(即它是描述符),则python将使用__get__
/ __set__
/ __del__
执行所有机制。
这就是为什么描述符方法中有一个“实例”参数的原因-您将描述符定义为类变量,但是__set__
方法将接收您的类的实际实例,因此您可以管理每个实例的数据,就像您的device