• Flask入门到精通(二)


    一、程序上下文

         Flask接收到来自客户端的请求后,路由到指定的接口进行响应处理并返回处理结果。响应接口需要知道客户端的请求体,即request对象才能进行正确的处理。如果给每个接口函数都传递一个request对象参数,太过冗余,且代码会很难看,因此Flask使用上下文临时将某些对象编程线程内的全局变量,即在同一个线程内,上下文信息可全局共享,且不会干扰到其他的线程环境。

         Flask有两种上下文,分别为程序上下文和请求上下文,各自对应的全局变量如下表:

    变量名 上下文 备注
    current_app 程序上下文 表示当前运行的程序实例
    g 程序上下文 处理请求时用作临时存储对象,每次请求都会重新设值
    request 请求上下文 客户端发来的request请求对象
    session 请求上下文 请求携带的会话信息

    Flask在分发请求之前会激活上下文信息,在请求处理完成后再删除。上下文只有在激活后,才可使用对应的全局变量,否则会报异常。

    app_ctx = app.app_context()    #可获取app对应的上下文

    app_ctx.push()  #推送上下文信息,即激活上下文

    二、请求钩子

    有时候,在请求开始或结束后,我们可能想要执行一些代码,比如,在请求开始前,完成数据库的连接,用户信息的认证等等。Flask使用装饰器为我们提供了注册通用函数的功能,支持的钩子函数有以下四种:

    before_first_request 第一次请求之前调用
    before_request 每次请求之前调用
    after_request 每次请求之后调用,前提是没有未处理的异常抛出
    teardown_request 每次请求之后调用,即使有未处理的异常抛出

    在请求函数和钩子函数之间,一般通过全局变量g实现数据共享。

    三、响应

    Flask的响应一般可包含三个参数,第一个参数指明响应的字符串,第二个参数可指明响应状态码,如200表示响应成功,第三个参数是由header首部组成的字典。我们可以通过make_response()生成一个response对象并设置。

     1 #!/usr/bin/env python
     2 # encoding: utf-8
     3 from flask import Flask
     4 from flask import request
     5 
     6 app = Flask(__name__)
     7 
     8 
     9 @app.route('/')
    10 def hello_world():
    11     return 'Hello World!'
    12 
    13 
    14 @app.route("/user/<user_name>")
    15 def hello_user(user_name):
    16     """
    17      动态路由示例
    18     :param user_name: 用户名
    19     :return:
    20     """
    21     1/0
    22     return "Hello %s" % user_name
    23 
    24 
    25 @app.route("/context")
    26 def get_context():
    27     """
    28      获取请求的上下文信息
    29     :return:
    30     """
    31     user_agent = request.headers.get("user-agent")
    32     return "your user-agent is %s" % user_agent
    33 
    34 
    35 @app.before_first_request
    36 def first_quest():
    37     print "run before first request"
    38 
    39 
    40 @app.before_request
    41 def every_request():
    42     print "One new request is comming"
    43 
    44 
    45 @app.after_request
    46 def after_r(exception):
    47     print "The request has done 1"
    48 
    49 @app.teardown_request
    50 def teardown_r(exception):
    51     print "The request has done 2"
    52 
    53 
    54 if __name__ == '__main__':
    55     app.run()

    上述代码运行后,在浏览器分别请求

    http://127.0.0.1:5000/ 输出:

        run before first request

        One new request is comming
       The request has done 1
       The request has done 2

    http://127.0.0.1:5000/user/patty 输出:

       One new request is comming
       The request has done 2

    变量共享:通过g实现

    1 @app.route('/')
    2 def hello_world():
    3     print g.user
    4     return 'Hello World!'
    5 
    6 @app.before_first_request
    7 def first_quest():
    8     g.user = 'tmp'
    9     print "run before first request"
  • 相关阅读:
    惊讶
    BLOG休假
    因考试得福
    Shape of My HeartSting !
    一个月的第一天了
    BLOG开张喽~~~
    该走了
    脏话
    EditText的属性
    游戏引擎
  • 原文地址:https://www.cnblogs.com/java-wgm/p/6602900.html
Copyright © 2020-2023  润新知