如何在 Python 中装饰 属性
How to decorate property in Python
我正在尝试为描述符 class 中的魔术方法 (__get__) 添加额外的装饰器。
我可以在使用@属性 时执行此操作,但在使用描述符class 时则不行。
我检查范围是因为我的对象集在总线上注册,一些寄存器只能取特定范围的值:
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
我可能错了,但很可能你的描述符根本没有被调用,装饰器不是问题。描述符意味着像
一样使用
class Foo2:
my_object = Register('my_object', 'init_value')
— 您将其定义为 class 属性。 python 将使用 __get__
/__set__
/__del__
执行所有机器,如果您的 class 属性支持它(即它是描述符)。
这就是描述符方法中有一个 "instance" 参数的原因——您将描述符定义为 class 变量,但是 __set__
方法将接收您的 class,因此您可以管理每个实例的数据,例如您的 device
我正在尝试为描述符 class 中的魔术方法 (__get__) 添加额外的装饰器。
我可以在使用@属性 时执行此操作,但在使用描述符class 时则不行。
我检查范围是因为我的对象集在总线上注册,一些寄存器只能取特定范围的值:
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
我可能错了,但很可能你的描述符根本没有被调用,装饰器不是问题。描述符意味着像
一样使用class Foo2:
my_object = Register('my_object', 'init_value')
— 您将其定义为 class 属性。 python 将使用 __get__
/__set__
/__del__
执行所有机器,如果您的 class 属性支持它(即它是描述符)。
这就是描述符方法中有一个 "instance" 参数的原因——您将描述符定义为 class 变量,但是 __set__
方法将接收您的 class,因此您可以管理每个实例的数据,例如您的 device