我想下面这些可以作为一个装饰师
class D:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, **kwargs)
class A:
@D
def f(self, x):
pass
a=A()
a.f(1)
但是我得到了TypeError: f() missing 1 required positional argument: 'x'
发生了什么,有没有一种方法可以像这样使用类作为装饰器
问题是,除了decorator机制之外,Python还使用了一种机制,使类主体内的函数像实例方法一样工作:它是"descriptor protocol"。这实际上很简单:所有函数对象都有一个
__get__
方法(而不是__set__
或__del__
)方法,这使它们成为“非数据描述符”。当Python从实例检索属性时,将使用实例作为参数调用__get__
,即__get__
方法。它们必须返回一个可调用的对象,该对象将用作方法,并且必须知道调用的实例是哪一个:这将打印“<;main。0x…>;1处的对象”
然而,由于很容易理解,这只允许一次在单个实例中调用修饰的方法——即使是拥有多个“a”实例的非并行代码,也可能在调用方法时考虑到错误的实例。也就是说,这个序列:
最终将调用“a2.f()”而不是“a1.f()”
为了避免这种情况,您必须返回一个可从
__get__
调用的,它不需要将实例作为类属性检索。一种方法是创建一个partial
可调用的函数并将其包含在内-但是,请注意,由于这是一个必要的步骤,因此装饰器类本身不需要在__call__
方法中具有“run wrapper+original code”函数-它可以有任何名称:相关问题 更多 >
编程相关推荐