场景介绍
很多些时候,在做 flask 程序的时候,我们需要用到一些全局变量,比如用户的登录信息等
blog 中的搜索功能,需要在不同的页面都显示搜索,最笨的方法是每个页面都实现一个搜索功能,但是这样太重复,太繁琐,违反了“简单”原则。一个好的程序员会把重复的事情都模块化,简单化。
我们可以每个 url 都用到了同意同一个搜索功能。这需要我们用到一个全局的搜索功能。
全揽:
- current_app # 当前激活程序的程序实例
- g # 处理请求时用作临时存储的对象。每次请求会重设这个变量
- request # 请求对象,封装了客户端发出的http请求中的内容
- session # 用户会话,用于存储请求之间需要‘记住‘的值的词典
图解
盗图了,改天我自己画一张详细的
一. g
1. 基本了解
g作为flask程序全局的一个临时变量,充当者中间媒介的作用,我们可以通过它传递一些数据
从0.10开始g兑现就不是在request的级别,而是在应用上下文的级别。flask从0.10开始g是和app绑定在一起了。
但不同请求的AppContext是不同的,所以g还是不同。也就是说你不能再一个视图中设置g.name,然后再另一个视图中使用g.name,会提示AttributeError。
-- 注意:大多数代码示例基于login函数,但是在实际项目中,给g赋值应基于登录校验的装饰器函数,在不同请求中,g 并不是同一个 g;换言之,当前请求完全结束时,当前的 g 也就销毁了 --
请求钩子: 说到g变量,就不得不说钩子函数
- before_first_request:注册一个函数,在处理第一个请求之前运行;
- before_request:注册一个函数,在每次请求之前运行;
- after_request:注册一个函数,如果没有未处理的异常抛出,在每次请求之后运行;
- teardown_request:注册一个函数,即使有未处理的异常抛出,也在每次请求之后运行
在请求钩子函数和视图函数之间共享数据一般使用上下文全局变量g。例如,before_request处理程序可以从数据库中加载已登录用户,并将其保存到g.user中。随后调用视图函数时,视图函数再使用g.user获取用户。
2. 实现原理
问题: 多线程的环境下,是如何保证request没有混乱的?
参考:
二. current_app
三. request
四. session