如果使用class.something = 2
为其分配值,并且如果像class.something(2, True)
那样调用方法,那么是否可以使装饰器使方法像属性一样工作?
更具体一点,我目前有以下
class attributeSetter(object):
''' Makes functions appear as attributes. Takes care of autologging.'''
def __init__(self, func):
self.func = func
def __set__(self, obj, value):
return self.func(obj, value)
def __repr__(self):
return repr(self.__getattribute__)
所以这个类有一个装饰方法:
class myClass(object):
@attributeSetter # decorated!
def myAttrib(self, value, add=False, subtract=False):
if add:
value += 2
if subtract:
value -= 2
self.__dict__['myAttrib'] = value
我可以这样做:
instance = myClass()
instance.myAttrib = 2 # sets the value to 2
instance.myAttrib *= 4 # now 8
print instance.myAttrib # 8
但是,我希望能够做到这一点:
instance.myAttrib(3, add=True) # now 8 + 3 + 2 = 13
instance.myAttrib(0, subtact=True) # now 13 + 0 - 2 = 11
print instance.myAttrib # 11
我的预感是,我只需要向attributeSetter
装饰器添加 __ call __ ,如下所示:
def __call__(self, *args, **kwargs):
self.func(*args, **kwargs)
然后它不会让我使用" ="设置值。语法。
我正在共同开发PsychoPy(一种用于心理学中的刺激传递的python模块),我们希望在设置每个刺激参数时进行一些处理,因此装饰者可以避免使用setter / getter方法。我们默认记录每个属性更改,但在某些情况下,用户希望使用额外的log = False参数禁用此特定设置的记录,或提供更多参数。因此,如果可以像使用函数/方法一样使用属性,那将是很好的,它实际上是首先。
答案 0 :(得分:3)
你需要实现一个__get__
method返回一个可调用的;你的装饰器已经提供了一个描述符对象,只需在作为属性访问时使其工作。
这可以像转身和绑定包装函数一样简单(所以你得到一个绑定方法):
class attributeSetter(object):
''' Makes functions appear as attributes. Takes care of autologging.'''
def __init__(self, func):
self.func = func
def __get__(self, instance, owner):
return self.func.__get__(instance, owner)
def __set__(self, obj, value):
return self.func(obj, value)
然而,这使得它与仅访问该属性不兼容! instance.myAttrib
现在返回一个绑定方法!你不能在这里双管齐下;方法只是绑定属性(因此通过描述符协议传递的属性)恰好是可调用的。
您当然可以从__get__
返回代理对象;一个实现__call__
方法的方法,并尝试尽可能多地作为底层托管实例属性(您的函数存储在self.__dict__['myAttrib']
中);但是这条路径充满了问题,因为代理对象永远不会真正 基础属性值。