def deco(func):
print "deco"
return func
@deco
def foo():
return "hello"
#main
if __name__=="__main__":
print foo()
装饰器理解起来就是
def deco(func):
print "deco"
return func
def foo():
return "hello"
#main
if __name__=="__main__":
fun = deco(foo)
print fun()
但是装饰器有个重要的特性就是在装饰的时候会调用一次
def deco(func):
print "deco"
return func
@deco
def foo():
return "hello"
#main
if __name__=="__main__":
pass
理解带参数的装饰器
def deco(**kw):
print kw
def _deco(func):
return func
return _deco
@deco(key="123")
def foo():
return "hello"
#main
if __name__=="__main__":
print foo()
理解起来就是
def deco(**kw):
print kw
def _deco(func):
return func
return _deco
def foo():
return "hello"
#main
if __name__=="__main__":
#print deco(key='123')(foo)()
fun = deco(key='123')(foo)
print fun()
利用装饰器在装饰时会调用一次,我们可以利用它在程序真正开始执行之前注册函数,以便方便的在需要的时候调用,实现逻辑解耦,举个栗子!
mapper={}
def deco(**kw):
key = kw['key']
def _deco(func):
#如没有注册到mapper中就把该函数注册进mapper
if key not in mapper:
mapper[key] = func
return func
return _deco
@deco(key='get')
def foo1():
return "call get"
@deco(key='post')
def foo2():
return "call post"
#main
if __name__=="__main__":
key = 'get'
#查找key=get的函数
call = mapper[key]
#调用这个函数
print call()
这样就形成了一个类似框架的东西,仔细观察的话,很像springMVC或者bottle,下一章节,我们就来用装饰器来封装一下python的web处理,服务器采用tornado,打算实现的最终目标如下:
@Router.route(url=r"hello/([a-z]+)",method=Router._GET|Router._POST)
def test(self,req,who):
#http://localhost:8888/hello/billy
return "Hi,"+who
@Router.route(url=r"greetings/([a-z]+)",method=Router._GET)
def test2(self,req,who):
#http://localhost:8888/greetings/rowland
raise Exception("error")
@Router.route(url=r"book/([a-z]+)/(\d+)",method=Router._GET|Router._POST)
def test3(self,req,categories,bookid):
#http://localhost:8888/book/medicine/49875
return "You are looking for a "+categories+" book\n"+"book No. " + bookid
@Router.route(url=r"json",method=Router._POST)
def test4(self,req):
#http://localhost:8888/json
#print req.request.body
who=req.json_args.get("who","default")
age=req.json_args.get("age",0)
person={}
person['who']=who
person['age']=int(age)
return person