Flask上下文管理session原理和全局g对象

Posted zzbj

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Flask上下文管理session原理和全局g对象相关的知识,希望对你有一定的参考价值。

一、一些python的知识

1、偏函数

def add(x, y, z):
    print(x + y + z)


# 原本的写法:x,y,z可以传任意数字
add(1,2,3)


# 如果我要实现一个功能,这三个数中,其中一个数必须是3
# 我们就可以使用偏函数来帮着我们传参
from functools import partial

# partial:给add这个函数固定传一个数字 3
new_add = partial(add, 3)

# 因此新的函数只需要传2个参数
new_add(1,1)
new_add(1,2)


# 偏函数:就是帮我们给一个函数固定一个参数
# new_add(x1, x2) --> add(3, x1, x2)

 

2、类的两个双下方法

1. __getattr__:对象获取属性值的时候触发

2. __setattr__:对象设置属性值的时候触发

3.示例
class A(object):
    def __init__(self):
        # self.name = {}
        # 初始化的时候,给这个对象设置一个属性名为name,值为空的字典
        object.__setattr__(self, "name", {})

    def __getattr__(self, item):
        print("getattr: ", item)

    def __setattr__(self, key, value):
        print("setattr: ", self.name)
        print("setattr: ", key, value)
        self.name[key] = value
        print("setattr: ", self.name)


# 实例化,调用__init__
a = A()

# 获取对象某个属性的值,会调用__getattr__
# 如果A这个类没有__getattr__,就会去执行父类的__getattr__
# 但是严谨的__getattr__是:如果你没有这个属性,就会给你报错
# 我们可以在A类重写__getattr__,可以让它不报错
a.xxx  # getattr:  xxx

# 给对象的某个属性设置值,会调用__setattr__
# 执行的逻辑跟__getattr__一样,A类没有就去调用父类的
a.xxx = 小明
# 首先打印name字典的默认值:是个空字典 setattr:  {}
# setattr的key是左边的变量,value是右边的值:setattr:  xxx 小明
# 打印self.name这个字典:setattr:  {‘xxx‘: ‘小明‘}

 

二、Flask上下文管理

Flask的上下文管理我们可以理解为一个生命周期
也就是请求进来到请求出去一共做了哪些事情
首先我们知道项目启动执行了app.run()方法,调用了werkzeug的run_simple()方法
run_simple(host, port, self, **options) 这时候的self就是我们的app
run_simple会执行self(),也就是app(), 那么app = Flask() 所以会走Flask的__call__方法

那么__call__做了什么呢
技术分享图片
environ是我们请求来的原始数据~当成参数传递给了request_context方法

 

技术分享图片
进入这个RequestContext对象

 

技术分享图片
这是初始化这个类做的一些事情
在这里重新封装了request, 以及给session 赋值了 None
也就是说:
ctx = RequestContext(app, environ)
ctx.request 是重新封装的request
ctx.session = None

 

继续
技术分享图片

技术分享图片
执行了_request_ctx_stack.push(ctx)
也就是说_request_ctx_stack它把我们的ctx对象push到了一个地方
我们的ctx这个对象里面有request以及session等

 


技术分享图片

技术分享图片

技术分享图片

技术分享图片

这个初始化方法就是刚才python类的双下方法__setattr__
就是给Local类初始化了两个属性    __storage__ = {}            __ident_func__ = get_ident

 

我们继续看LocalStark中push方法做了什么
技术分享图片

技术分享图片

技术分享图片

技术分享图片

技术分享图片
现在回去看wsgi_app里的ctx.push(),到这里,它就走完了,接下来就要走视图
那到这里我们可以通过什么样的方法在我们视图中拿到这个request对象呢
request在ctx对象里能通过ctx.request得到,那我们怎么得到ctx呢
ctx被LocalStack对象放入到Local中了

技术分享图片

技术分享图片
from flask import Flask
from flask import globals

app = Flask(__name__)


@app.route("/")
def index():
    ctx = globals._request_ctx_stack.top
    print(ctx.request.method)
    return "index"



if __name__ == __main__:
    app.run()
获取ctx

 

三、Flask上下文管理(续)

 

 

 

四、session的实现原理

 

 

 

五、应用上下文管理

 

 

 

六、全局对象g

 

以上是关于Flask上下文管理session原理和全局g对象的主要内容,如果未能解决你的问题,请参考以下文章

在Flask中,g是什么?它的生命周期是?能做什么?

flask---第一篇

Flask 学习-66.全局g对象的使用

flask-06 flask上下文和钩子

Flask基础:sessionflash特殊装饰器蓝图路由正则匹配上下文管理 & flask-session

flask上下文管理