我正在尝试创建一个与我的目的类似的装饰器,但是我的实现(在纯Pythonproperty
中类似)不起作用。在包装之前我无法访问类变量。这是一个最小的可重现示例:property
self
class MyWrapper(object):
def __init__(self, first=None, second=None) -> None:
self.first = first
self.second = second
def __call__(self, *args, **kwargs):
if self.first is not None:
self.first(*args, **kwargs)
if self.second is not None:
self.second(*args, **kwargs)
def second_handler(self, func):
wrapper = type(self)(self.first, func)
return wrapper
class TestClass(object):
def __init__(self, name) -> None:
self.name = name
@MyWrapper
def foo(self):
print(f'Hello, {self.name}!')
@foo.second_handler
def foo(self):
print(f'Bye, {self.name}!')
def main(*args, **kwargs):
instance = TestClass('User')
instance.foo()
if __name__ == '__main__':
main()
应该输出:
Hi User!
Bye, User!
在调用时,self
它被装饰器替换,我与原始类的属性失去了联系。
您需要实现一个描述符 - 一个包含方法的特殊类
__get__
(以及其他方法,例如__set__
,如果您需要重写对对象属性的分配)。这样的类可以用作方法的装饰器。实际上,在您链接的示例中,property
它是作为描述符实现的(方法__get__
、__set__
、__delete__
、__set_name__
是特定于描述符的方法)。我不得不稍微调整它,因为我没有立即记住它是如何工作的,一个最小的例子是这样的:
在这里,
__get__
当尝试访问 attribute 时foo
,它将被调用,并且obj
请求该 attribute 的对象将被传递到其参数中;它必须像self
调用保存的方法时一样保存和使用。