20行代码告诉你Flask的route装饰器原理



  • 重点讲解:
    装饰器(@)是Python中非常重要的『东西』,你在微博中艾特谁,她还是她,你改变不了她。但是在python中你艾特了某个函数,你将对它拥有控制权,哪怕把它改的面目全非也是可以的。
    装饰器是什么意思呢?
    装饰器就是一个接受函数对象的函数,好吧,有点绕口,请看代码:

    class Girl():
        def __init__(self):
            self.msg = "Girl:I dislike you!"
        def output(self):
            return self.msg
    
    def Change(obj):
        # 洗脑模式
        obj.msg = "Girl:I like you!"
        return obj
    
    print Change(Girl()).output()
    # 输出结果:Girl:I like you!
    

    那么显然写成Change(Girl()).output()不是很直观,我们来换一种更Pythoner的:
    直接通过装饰器去改写输出函数output,在函数输出前修改msg数据

    def ChangeOutput(msg):
        def change_output(func):
            def new_output(s):
                s.msg = "Girl:I like you!"
                return func(s)
            return new_output
        return change_output
    
    class Girl():
        instance = None
        def __init__(self):
            self.msg = "Girl:I dislike you!"
    
        @ChangeOutput("Girl:I link you!")
        def output(self):
            return self.msg
    
    print Girl().output()
    

    下面就是用装饰器来模拟Flask的原理了。

    # -*- coding: utf-8 -*-
    class GuaikNet():
        def __init__(self):
            # URI与处理函数的映射
            self._func_map = {}
    
        def route(self, uri):       # 装饰器,用来接受参数
            def _new_func(func):    # 新的函数对象,用来替代被装饰的函数,参数为被装饰的函数对象
                self._func_map[uri] = func
                return func
            return _new_func
    
        def server(self, uri):
            func = self._func_map[uri]
            if func:
                return func()
            else:
                raise ValueError('Route "{}" has not been registered'.format(uri))
    
    app = GuaikNet()
    @app.route("/")
    def hello():
        return "Hello GuaikNet"
    
    print app.server("/")
    

Log in to reply