[Python]从装饰器说开去

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

你可能感兴趣的:(框架,线程,python,tornado,装饰器)