zoukankan      html  css  js  c++  java
  • Flask 第十五话之请求上下文及全局全局存储g对象

    一、简介

    在 flask 中,视图函数需要知道它执行情况的请求信息(请求的 url,参数,方法等)以及应用信息(应用中初始化的数据库等),才能够正确运行。

    最直观地做法是把这些信息封装成一个对象,作为参数传递给视图函数。但是这样的话,所有的视图函数都需要添加对应的参数,即使该函数内部并没有使用到它。

    flask 的做法是把这些信息作为类似全局变量的东西,视图函数需要的时候,可以使用 from flask import request 获取。但是这些对象和全局变量不同的是——它们必须是动态的,因为在多线程或者多协程的情况下,每个线程或者协程获取的都是自己独特的对象,不会互相干扰。

    那么如何实现这种效果呢?如果对 python 多线程比较熟悉的话,应该知道多线程中有个非常类似的概念  threading.local,可以实现多线程访问某个变量的时候只看到自己的数据。内部的原理说起来也很简单,这个对象有一个字典,保存了线程 id 对应的数据,读取该对象的时候,它动态地查询当前线程 id 对应的数据。

    flask 中有两种上下文:application context 和 request context。上下文有关的内容定义在 globals.py 文件。

    二、应用上下文使用

    from flask import Flask,request,session,current_app,url_for,g
    from werkzeug.local import Local,LocalStack
    
    app = Flask(__name__)
    
    # 应用上下文:写法一
    app_context  = app.app_context()
    app_context.push()
    print(current_app.name)
    
    # 应用上下文:写法二
    # 只能在with函数内容
    with app.app_context():
        print(current_app.name)
    
    @app.route('/')
    def hello_world():
        print(url_for('mylist'))
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run()

    三、请求上下文使用

    from flask import Flask,request,session,current_app,url_for,g
    from werkzeug.local import Local,LocalStack
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        print(url_for('mylist'))
        return 'Hello World!'
    
    
    @app.route('/list/')
    def mylist():
        return 'Hello World!'
    
    # 请求上下文
    with app.test_request_context():
        # 手动推入一个请求上下文到请求上下文栈中
        # 如果没有请求上下文,那么先推入一个应用上下文到栈中
        print(url_for('mylist'))
    
    if __name__ == '__main__':
        app.run()

     四、g对象

    注:g对象是全局flask中运行时都可以访问的对象,并且和request一样也是线程隔离的,是专门用于开发者自己定义的存储对象,方便于在整个项目组获取和使用

    from flask import Flask,request,g
    from utils import *
    
    app = Flask(__name__)
    
    @app.route('/')
    def hello_world():
        username = request.args.get('username')
        g.username = username
        log_a()
        log_b()
        log_c()
        print(url_for('mylist'))
        return 'Hello World!'
    
    
    if __name__ == '__main__':
        app.run()

    utils.py:其他函数中调用g对象

    from flask import g
    
    def log_a():
        print('log a %s'%g.username)
    
    def log_b():
        print('log b %s'%g.username)
    
    def log_c():
        print('log c %s'%g.username)
  • 相关阅读:
    在插入一条记录后 取得自动增长ID
    hashtable,dictionary 从原理上说说有什么异同,哪个性能高一些
    单例模式
    聚簇索引与非聚簇索引的区别
    基于SQL SERVER2008的SCCM2007部署
    XML架构下的表结构设置主键
    IE6与IE7下一点样式的区别
    Session丢失原因与解决方案小结
    Python_如何去除字符串里的空格
    Python_让人脑阔疼的编码问题(转)+(整理)
  • 原文地址:https://www.cnblogs.com/lee-xingxing/p/12496460.html
Copyright © 2011-2022 走看看