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