gpt4 book ai didi

python - 在描述符中,__call__ 是否可以访问使用装饰器的类?

转载 作者:行者123 更新时间:2023-11-28 22:03:45 26 4
gpt4 key购买 nike

考虑以下代码:

class MyCustomDescriptor:
def __init__(self,foo):
self._foo = foo

def __call__(self,decorated_method):
# Here's my question... Is there any way to get a reference to the
# type (ClassA or ClassB) here?
return self

def __get__(self,instance,type):
# Clearly at this point I can get the type of the class.
# But it's too late, I would have liked
# to get it back in __call__.
return 10

class ClassA:
@MyCustomDescriptor(foo=1)
def some_value(self): pass

class ClassB:
@MyCustomDescriptor(foo=1)
def some_value(self): pass

我想要获得对该类的引用的原因是我想使用装饰函数/方法向该类添加一些静态数据。我意识到这有点不典型,但对于我正在做的事情,它会有所帮助。

回答 - 无法完成。根据下面的响应之一,我从调用中检查了堆栈,并能够获得使用描述符的完全限定类(在我的示例中为 ClassA 或 ClassB)。但是您不能将其转换为类型/类,因为类型/类仍在被解析(或者 python 中的任何正确术语)。换句话说,python 遇到 ClassA 并开始解析它。在解析它时,它会遇到描述符并调用 init 并调用描述符。 ClassA 仍未完成解析。因此,尽管您可以从调用中获得完全限定的模块/类名称,但您无法将其转换为类型。

最佳答案

在应用装饰器的地方,some_value 只是一个函数,而不是方法。所以,不,函数无法知道它与特定类相关联。

两种选择是:

  • 将类名传递给 MyCustomDescriptor(连同 foo),或者
  • 使用类装饰器创建描述符 some_value

类装饰器可能看起来像这样:

def register(method_name,foo):
def class_decorator(cls):
method=getattr(cls,method_name)
class MyCustomDescriptor(object):
def __get__(self,instance,type):
result=method(instance)
return '{c}: {r}'.format(c=cls.__name__,r=result)
setattr(cls,method_name,MyCustomDescriptor())
return cls
return class_decorator

@register('some_value',foo=1)
class ClassA:
def some_value(self):
return 10

比如运行

a=ClassA()
print(a.some_value)

产量

ClassA: 10

关于python - 在描述符中,__call__ 是否可以访问使用装饰器的类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8438987/

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