我用一个类编写了一个装饰器。
class to_uppercase:
def __init__(self, func):
self.func = func
def __call__(self, *args, **kwargs):
return self.func(*args, *kwargs).upper()
当我在一个函数上应用这个装饰器时,它工作了。
x一个一个一个一个x一个一个二个x
现在,当我在一个方法上应用相同的装饰器时,我得到一个错误。
class base_string:
def __init__(self, base):
self.base = base
@to_uppercase
def get_base_string(self):
return self.base
s = base_string('word worD')
s.get_base_string()
类型错误:get_base_string()缺少1个必需的位置参数:"自我"
我错过了什么?
2条答案
按热度按时间wgx48brx1#
使用函数而不是类,但是如果你需要一个类,这里你可以做什么。
在类中添加
__get__
方法当你使用一个类作为装饰器时,get_base_string现在是你的类装饰器的一个示例:
所以,当函数被调用时,
self
是对to_uppercase
的引用,而你没有对s
对象的引用。来自https://stackoverflow.com/a/3296318/6251742的代码
通过这个方法,你可以与Python交互,获取装饰器示例,因为你是从另一个对象调用它的,所以这个对象和他的类型被发送到
obj
参数中的__get__
方法,他的类型被发送到obj_type
参数中。如果没有
__get__
方法,则被调用的函数是decorator的__call__
,其中self
引用decorator示例,并且没有提供装饰该方法的类的示例因此我们需要返回一个可调用对象,其中我们修饰方法的类的示例作为第一个位置参数提供,这就是
functools.partial
和obj
(我们需要的self
示例)的操作,然后这个partial将被调用。qqrboqgw2#
外部函数的装饰器基本上工作正常
类方法的装饰器工作不正常
在装饰器中使用描述符协议将允许我们访问用self
这样的正确示例装饰的方法。
有关详细信息或了解,请访问https://docs.python.org/3/howto/descriptor.html
更多示例Python decorator, self is mixed up
Decorating class methods - how to pass the instance to the decorator?