我正在尝试编写一个类似于@property的装饰器,但遇到了一些问题。
class Dec(object):
def __init__(self, fn):
self._fn = fn
self._before = None
@property
def before(self)
return self._before
@before.setter
def before(self, fn):
self._before = fn
def __call__(self, *args, **kwargs):
self._before(*args, **kwargs)
self._fn(*args, **kwargs)
def withbefore(fn):
return Dec(fn)
它是一个简单的链接装饰器。 @property/@.setter 语法正是我想要克隆的。
这有效:
@withbefore
def foo():
...
@foo.before
def beforefoo():
...
但在类里面却没有:
class Weee(object):
@withbefore
def do_stuff(self):
pass
@do_stuff.before
def before_do_stuff(self):
pass
它会引发导入错误。
TypeError: 'NoneType' object is not callable
如何正确模拟@property/.{setter,getter,deleter}?
最佳答案
实际上,它会引发 TypeError。
无论如何,在使用函数运行装饰器时我也遇到了同样的错误。发生这种情况是因为,当您使用 @foo.before
修饰函数时,它将调用 self._before
函数,并将修饰后的函数作为参数。由于 self._before
为 None
,因此会引发错误。
有多种解决方案。我最喜欢的是为 self._before
设置一个不同的默认值 - 一个将设置 self._before
值的函数:
class Dec(object):
def __init__(self, fn):
self._fn = fn
def setbefore(b):
self._before = b
self._before = self.default_before = setbefore
当然,这个函数不应该在调用Dec
对象时被调用,所以我们改变__call__
方法:
def __call__(self, *args, **kwargs):
if self._before != self.default_before:
self._before(*args, **kwargs)
self._fn(*args, **kwargs)
关于python - 在 Python 2.7 中定义类似 "property"的装饰器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10787667/