• 理解@app.route()


     

    from flask import Flask
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        return 'Hello World!'
    if __name__ == '__main__':
        app.run()
    
    

    我觉得只要稍微看过 Flask 官方教程的小伙伴都会对这个代码很熟悉,熟悉归熟悉,那小伙伴们理解 **@app.route()**是如何发挥作用的吗?如果不清楚的话,嗯哼,just follow me~~

    在理解这个之前,我们需要做一些准备。

    @app.route 和 装饰器

    为了理解 @app.route() 是如何发挥作用的,我们首先需要对 Python 中的装饰器有个大体的认识。具体的可以参考廖老师的教程--装饰器。老实说,装饰器其实就是在一个函数内部定义另外一个函数,然后返回一个新的函数,即动态的给一个对象添加额外的职责。如果还不是很明白的话,没关系,我们来看看具体的例子。

    def simple_decorator(f):
        def wrapper():
            print "func enter"
            f()
            print "func exit"
        return wrapper
    
    @simple_decorator
    def hello():
        print "Hello World!"
        
    hello()
    
    

    运行一下上述代码,我们将会看到如下的输出:

     

    看完这个例子,小伙伴们有没有稍微理解一点 @app.route() 了呢?可能有的小伙伴会说,@app.route() 是带参的,我们的装饰器并没有任何参数,这个很简单,接下来让我们试着,让我们的装饰器也可以传递参数。

    def not_very_simply_decorator(enter_msg,exit_msg):
        def simple_decorator(f):
            def wrapper():
                print enter_msg
                f()
                print exit_msg
            return wrapper
        return simple_decorator
    
    @not_very_simply_decorator("func enter","func exit")
    def hello():
        print "Hello World"
    
    hello()

    是不是很奇怪,我为啥让两次的输出信息都一样,因为那样子,我只需要截一次图了~~哈哈,有没有觉得这个跟 app.route() 越来越有点像了,有的小伙伴肯定要说了,人家是 app.route(),而我的是 func(),那我只能说,咱们再接着往下看。

    从 route() 到 app.route()的不归路

    在此之前,如果有小伙伴跟我一样用 Pycharm 的话,使用它直接创建一个 Flask 项目,然后去点击 app.route()的话,会发现它跳转到了一个 Flask.py 的文件内,这个文件内容是一个 Flask 对象,而我们的 route() 函数就在其中,为了更好的理解 Flask 对象,我们可以尝试模仿它,创建一个类似的 Flask 对象。

    class FlaskBother():
        def route(self,route_str):
            def decorator(f):
                return f
            return decorator
    
    app = FlaskBother()
    
    @app.route('/')
    def hello():
        return 'Hello World'
    

    看到这里,我就问一句,像不像?这个和我们之前创建的装饰器的主要区别在于,我们不想去修改我们装饰的这个函数的功能,我们只想去引用它,so 重点来了,聪明的你们知道,我们需要什么吗~~我们需要一个变量去存储路由和其关联的函数。那么 Flask 有没有这个变量呢,答案是肯定的,那我们如何在 Flask 中去查看所有的路由,以最初的最小的 Flask 为例。

    进入Python交互模式

    >>> from Hello import app
    
    >>> app.url_map
    
    Map([<Rule '/' (HEAD, OPTIONS, GET) -> hello>,
    
     <Rule '/static/<filename>' (HEAD, OPTIONS, GET) -> static>])
    

    好了说完在 Flask 中如何查看所有路由,为了在我们的 FlaskBother实现同样的功能,我们添加一个 "route" 字典到我们 FlaskBother 对象中。当我们的装饰器被调用的时候,我们将路由和关联的函数保存到我们的 "route" 字典中去。

    class FlaskBother():
        def __init__(self):
            self.routes = {}
        def route(self,route_str):
            def decorator(f):
                self.routes[route_str] = f
                return f
            return decorator
    
    app = FlaskBother()
    
    @app.route("/")
    def hello()
        return "Hello World"
    
    

    其实到这里我们基本上已经完成了百分之90%了,我们现在唯一欠缺是一个可以访问内部 route 的途径,所以让我们再添加一个函数 server(path),通过这个函数我们可以通过路由去访问其关联的函数,如果没有的话,自然返回一个错误。

    class FlaskBother():
        def __init__(self):
            self.routes = {}
        def route(self,route_str):
            def decorator(f):
                self.routes[route_str] = f
                return f
            return decorator
        
        def server(self,path):
            view_function = self.routes.get(path)
            if view_function:
                return view_function()
            else:
                 raise ValueError('Route "{}" has not been registered'.format(path))
    
    

    这就算完了吗?并没有,让我们尝试运行下面的程序:

    app = FlaskBohter()
    @app.route("/")
    def hello():
        return "Hello World"
    
    print app.server("/")
    

     

    到这里不知道小伙伴们对 @app.route() 有没有一点理解~~如果还没有理解的话,不要急,我们慢慢来,如何将server(path) 挂载到 HTTP 服务器这里就不说了~~好了,小伙伴们下次见~~

    欢迎小伙伴们扫码我的头像,关注我的微信号~我是桃子,和有趣的桃子用Python做有趣的事情。

    编辑于 2018-09-15
  • 相关阅读:
    hbase 导入导出、hbase shell 基本命令。
    一道java基础面试题
    sqoop2报错
    测试往博客上放音乐
    java 压缩文件
    java 提取目录下所有子目录的文件到指定位置
    3.Git的常用操作
    2.Git客户端安装
    1.Git的由来
    『Spring』IOC创建对象的方式
  • 原文地址:https://www.cnblogs.com/sddai/p/13426277.html
Copyright © 2020-2023  润新知