[Python]从装饰器说开去
程序员文章站
2022-06-14 17:35:21
...
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