Python3无法将@property作为decorator参数传递



我已经实现了decorator,它可以接收额外的参数,并希望将其与类方法一起使用。我想把@property作为decorator参数传递,但我得到的不是@property结果:

<property object at 0x7f50f5195230>

这是我的装饰师:

class Decorator(object):
def __init__(self, some_arg):
self.func = None
self.some_arg = some_arg
def __get__(self, instance, owner):
import functools
return functools.partial(self.__call__, instance)
def __call__(self, func):
self.func = func
def wrapper(*args, **kwargs):
return self._process_sync(*args, **kwargs)
return wrapper
def _process_sync(self, *args, **kwargs):
try:
print(self.some_arg)
return self.func(*args, **kwargs)
except Exception as e:
print(e)
return None

我的测试课程:

class Test(object):
@property
def some_data(self):
return {'key': 'value'}
@Decorator(some_data)
def some_method(self):
print('method output')
return None

用法:

test = Test()
test.some_method()

两个问题:

  1. 如何正确传递属性以接收@property结果而不是<property object at 0x7f50f5195230>
  2. 如果类属性/方法在下面的代码中,是否可以将它们传递给decorator

property对象是一个描述符。要从中获取值,需要使用适当的实例调用其__get__方法。由于Decorator对象有很多不同的角色,因此在当前代码中确定何时执行这一操作并不容易。它既是一个装饰器工厂(在@Decorator(x)行中用一个参数初始化(,也是装饰器本身(用要装饰的函数调用(。您给了它一个__get__方法,但我不希望它被使用,因为Decorator的实例从未被分配给类变量(只有从__call__返回的包装函数(。

无论如何,这里有一个修改版本,Decorator处理描述符协议本身的几乎所有部分:

class Decorator:
def __init__(self, arg):
self.arg = arg      # this might be a descriptor, like a property or unbound method
def __call__(self, func):
self.func = func
return self         # we still want to be the descriptor in the class
def __get__(self, instance, owner):
try:
arg = self.arg.__get__(instance, owner)   # try to bind the arg to the instance
except AttributeError: # if it doesn't work, self.arg is not a descriptor, that's OK
arg = self.arg
def wrapper(*args, **kwargs):   # this is our version of a bound method object
print(arg) # do something with the bound arg here
return self.func.__get__(instance, owner)(*args, **kwargs)
return wrapper

最新更新