class myDecorator(object):
def __init__(self, fn):
print "inside myDecorator.__init__()"
self.fn = fn
def __call__(self):
self.fn()
print "inside myDecorator.__call__()"
@myDecorator
def aFunction():
print "inside aFunction()"
print "Finished decorating aFunction()"
aFunction()
# 输出:
# inside myDecorator.__init__()
# Finished decorating aFunction()
# inside aFunction()
# inside myDecorator.__call__()
上面这个示例展示了,用类的方式声明一个decorator。我们可以看到这个类中有两个成员:
1)一个是__init__(),这个方法是在我们给某个函数decorator时被调用,所以,需要有一个fn的参数,也就是被decorator的函数。
2)一个是__call__(),这个方法是在我们调用被decorator函数时被调用的。
上面输出可以看到整个程序的执行顺序。
__init()__可以看成函数式decorator中外层函数
__call()__可以看成函数式decorator中的内层函数
上面的class可以看成以下函数形式
def myDecorator(fn):
print ("inside myDecorator.__init__()")
def newDecorator():
fn();
print ("inside myDecorator.__call__()")
return newDecorator
思考:
class makeHtmlTagClass(object):
def __init__(self, tag, css_class=""):
self._tag = tag
self._css_class = " class='{0}'".format(css_class) \
if css_class !="" else ""
def __call__(self, fn):
def wrapped(*args, **kwargs):
return "<" + self._tag + self._css_class+">" \
+ fn(*args, **kwargs) + "</" + self._tag + ">"
return wrapped
@makeHtmlTagClass(tag="b", css_class="bold_css")
@makeHtmlTagClass(tag="i", css_class="italic_css")
def hello(name):
return "Hello, {}".format(name)
print (hello("Hao Chen"))
结果
<b class='bold_css'><i class='italic_css'>Hello, Hao Chen</i></b>