gpt4 book ai didi

Python3 不可能将 @property 作为装饰器参数传递

转载 作者:行者123 更新时间:2023-12-01 00:26:02 24 4
gpt4 key购买 nike

我已经实现了可以接收额外参数的装饰器,并希望将其与类方法一起使用。我想传递 @property 作为装饰器参数,但我得到的不是 @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. 如果类属性/方法位于代码下方,是否可以将它们传递给装饰器?

最佳答案

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

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

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

关于Python3 不可能将 @property 作为装饰器参数传递,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58582507/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com