【发布时间】:2019-11-26 22:28:12
【问题描述】:
我在使用包装类时遇到问题,无法弄清楚我做错了什么。 如何让该包装器与任何带有“self”参数的类函数一起工作?
这适用于 Python 3.7.3。 问题是我记得包装器以前工作过,但似乎发生了一些变化……也许我现在做错了,而我以前没有。
class SomeWrapper:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
# this fails because self is not passed
# ERROR: __init__() missing 1 required positional argument: 'self'
func_ret = self.func(*args, **kwargs)
# this is also wrong, because that's the wrong "self"
# ERROR: 'SomeWrapper' object has no attribute 'some_func'
# func_ret = self.func(self, *args, **kwargs)
return func_ret
class SomeClass:
SOME_VAL = False
def __init__(self):
self.some_func()
print("Success")
@SomeWrapper
def some_func(self):
self.SOME_VAL = True
def print_val(self):
print(self.SOME_VAL)
SomeClass().print_val()
【问题讨论】:
-
__call__方法应该返回一个可调用对象,而不是调用可调用对象的结果。装饰器应该是它的一个实例,而不是类。 -
不只是装饰器函数的情况吗?我的印象是你可以在
__call__中调用装饰函数。 -
是的——在这方面你是对的——克劳斯弄错了。
-
将首先调用该类,并将要装饰的方法作为“func”参数传递给
__init__。结果实例是可调用的,因为该类有一个__call__方法,并且当从类实例中调用此实例时,它将运行。是的,我确信这一点。self信息未插入,因为在方法调用中附加此信息的语言机制使用类的__get__方法,如下所述。 -
@jsbueno 我明白了。
标签: python decorator python-decorators callable