我试图在类中修饰一个方法,但python引发了一个错误。我的班级看起来像这样:
from pageutils import formatHeader
class myPage(object):
def __init__(self):
self.PageName = ''
def createPage(self):
pageHeader = self.createHeader()
@formatHeader #<----- decorator
def createHeader(self):
return "Page Header ",self.PageName
if __name__=="__main__":
page = myPage()
page.PageName = 'My Page'
page.createPage()
pageutils.py
:
def formatHeader(fn):
def wrapped():
return '<div class="page_header">'+fn()+'</div>'
return wrapped
Python抛出以下错误
self.createHeader()
TypeError: wrapped() takes no arguments (1 given)
我在哪里玩耍?
答案 0 :(得分:56)
您省略了未修饰函数中存在的self参数(在您的情况下为createHeader)。
def formatHeader(fn):
from functools import wraps
@wraps(fn)
def wrapper(self):
return '<div class="page_header">'+fn(self)+'</div>'
return wrapper
如果您不确定要装饰的功能的签名,可以按照以下方式使其更加通用:
def formatHeader(fn):
from functools import wraps
@wraps(fn)
def wrapper(*args, **kw):
return '<div class="page_header">'+fn(*args, **kw)+'</div>'
return wrapper
答案 1 :(得分:32)
Python自动将类实例作为引用传递。 (在所有类方法中看到的self
参数)。
你可以这样做:
def formatHeader(fn):
def wrapped(self=None):
return '<div class="page_header">'+fn(self)+'</div>'
return wrapped
答案 2 :(得分:0)
您还可以在运行时(而不是在定义时)修饰该方法。例如,在您无权访问或不想编辑源代码的情况下,这可能很有用。
In [1]: class Toy():
...: def __init__(self):
...: return
...: def shout(self, s):
...: print(s)
...:
In [2]: def decor(fn):
...: def wrapper(*args):
...: print("I'm decorated")
...: return fn(*args)
...: return wrapper
...:
In [4]:
In [4]: a=Toy()
In [5]: a.shout('sa')
sa
In [6]: a.shout=decor(a.shout)
In [7]: a.shout('sa')
I'm decorated
sa