标签:
装饰器的本质:
当你在用某个@decorator来修饰某个函数func时,如下所示:
@decorator def func(): pass
其解释器会解释成下面这样的语句:
func=decorator(func)
本质是把一个函数当作参数传递到另一个函数中,然后再调用。
def hello(fn): def wrapper(): print "hello,%s" %fn.__name__ fn() print "goodbye,%s" %fn.__name__ return wrapper @hello def foo(): print "I am foo" >>>foo() "hello,foo" "I am foo" "goodbye,foo"
hello(foo)返回了wrapper()函数,所以foo其实变成了wrapper的一个变量,而后面的foo()执行其实变成了wrapper()
多个装饰器:
@decorator_one @decorator_two def func(): pass
相当于func=decorator_one(decorator_two(func))
带参数的装饰器:
@decorator(arg1,arg2) def func(): pass
相当于func=decorator(arg1,arg2)(func).这意味着decorator(arg1,arg2)这个函数需要返回一个“真正的装饰器”。
def mydecorator(arg1,arg2): def _mydecorator1(func): def _mydecorator2(*args,**kw): res=func(*args,**kw) return res return _mydecorator2 return _mydecorator1
上面的函数返回的_mydecorator1才是真正的装饰器。因此,当装饰器需要参数时,必须使用第二集封装。因为装饰器在模块第一次被读取时由解释程序装入,所以它们的使用必须受限于总体上可以应用的封装器。
带参数及多个装饰器:
def makeHtmlTag(tag,*args,**kwds): def real_decorator(fn): css_class="class=‘{0}‘".format(kwds["css_class"]) if "css_class" in kwds else "" def wrapped(*args,**kwds): return "<"+tag+css_class+">"+fn(*args,**kwds)+"</"+tag+">" return warpped(*args,**kwds) return real_decorator
@makeHtmlTag(tag=‘i‘,css_class=‘italic_css‘) @makeHtmlTag(tag=‘b‘,css_class=‘bold_css‘) def hello(): return "hello world" >>>hello() <i class=‘italic_css‘><b class=‘bold_css‘>hello world</b></i>
class式装饰器:
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 myfunc(): print "inside myfunc" >>>myfunc "inside mydecorator--init" "inside myfunc" "inside mydecorator--call"
重写makeHtmlTag代码:
标签:
原文地址:http://my.oschina.net/935572630/blog/393489