2023年8月3日发(作者:)

Flask学习笔记总结(⼀)Flask学习笔记总结(⼀)说明:开始在csdn上⾯记录⼀些关于⾃⼰学习技术的笔记总结。⽂章⽬录前⾔在IT⾏业中是需要不断去学习和拓展⾃⼰的知识⾯的,只有不断接触新知识才能不断提⾼⾃⼰的能⼒和价值,我相信没有知识是⽩学的,希望⾃⼰能成为⼀个好的程序员。提⽰:个⼈学习随笔,⾃⼰记录使⽤,仅供参考⼀、python的web三⼤框架:重武器 组件超多 便捷 例 ORM FORM modelform 缓存 session2. Flask: 短⼩精悍 第三⽅组件较为丰富 开发⼩的⽤flask,路由较为特殊:基于装饰器实现,但究其本质还是通过add_url_rule来实现.conf 为配置⽂件3. Tornado:异步⾮阻塞框架() 1线程跑 1000个任务⼆、flask⼊门对于Werkzeug本质是Socket服务端,其⽤于接收http请求并对请求进⾏预处理,然后触发Flask框架本质Werkzeug⽰例:代码如下:from rs import Request, Response@ationdef hello(request): return Response('Hello World!')if __name__ == '__main__': from g import run_simple run_simple('localhost', 4000, hello) # 看到run_simple代表socket执⾏ 监听端⼝代码如下(⽰例):from flask import Flask#实例化flask对象app = Flask(__name__) ###将'/'和 index的对应关系添加到路由器中"""{ '/':index}"""@('/') #装饰器 两步 相当于 先执⾏ v=('/') 再执⾏ v()#def hello_world(): return 'Hello World!'

if __name__ == '__main__': # 监听⽤户请求 #如果有请求 则执⾏app的__call__⽅法 () #运⾏ 等待连接 与run_simple有关联3.⽤户demo1.登录界⾯(主程序)代码如下(⽰例):from flask import Flask,render_template,request,redirect#render_template是表⽰页⾯模板 request请求相关全放⼊⾥⾯# 实例化flask对象app = Flask(__name__)@('/login',methods=['GET',"POST"]) # 装饰器 两步 相当于 先执⾏ v=('/') 再执⾏ v()def index(): if == "GET": return render_template('') else: user = ('user') pwd = ('pwd') if user == 'lixuan' and pwd == '123': return redirect('') return render_template('',error='⽤户名或密码错误')# url的所有数据都在query_string内if __name__ == '__main__': # 监听⽤户请求 # 如果有请求 则执⾏app的__call__⽅法 () # 运⾏ 等待连接 与run_simple有关联2.⽹页程序() Title

⽤户登录

{{error}}
3.⽤户列表展⽰装饰器:⽤户认证装饰器demo代码如下:def wrapper(func) def inner(*arg,**kwargs) return func(*arg,**kwargs) return inner@wrapper #执⾏wrapper并将下⾯当参数 index=wrapper(index)def index(request): pass

登录函数内:session[‘user_info’] = user外函数判断(弃⽤了):user = ('user_info') if not user: url = url_for('l1') return redirect(url)三、配置⽂件:设置⽅法1 [‘DEBUG’] = True设置⽅法2 = True-设置⽅法2 = True设置⽅法3 最规范直接做⼀个 然后去调⽤即可main⽂件: _object(“python类或类的路径”)例: _object(‘pro_gConfig’)内的类:class TestingConfig(Config):—— TESTING = Trueps:知识点django rest frameworkdjango 中间件需求:cpu占⽤90%,发送警报:邮件。。。。数据库操作:mysql。。。。缓存放在redis/memcache 调换使⽤ 可以放在配置⽂件去if else四、路由系统 需要扩展 (diango可直接实现):1.代码如下:def route(self, rule, **options):

def decorator(f): endpoint = ('endpoint', None) _url_rule(rule, endpoint, f, **options) #add_url_rule加到路由表中 return f return decoratordef

可⽀持cbv 层层嵌套继承url重定向 、 为保留原地址可⽤ : redirect_to="/新地址后缀“subdomain=None #代表域名前部2. 域名变化@("/dynamic", subdomain="")def username_index(username): """Dynamic subdomains are also supported Try going to /dynamic""" return username + "."

ps : c-window-system32-drivers-etc-hosts 修改域名,测试⼈员常⽤

username : 字符串int:post_id :整型3.正则表达式需进⾏⾃制创建类 class RegexConverter(BaseConverter):

""" ⾃定义URL匹配正则表达式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值 :param value:

:return:

""" return int(value) #格式检测转换 def to_url(self, value): """ 使⽤url_for反向⽣成URL时,传递的参数经过该⽅法处理,返回的值⽤于⽣成URL中的参数 :param value:

:return:

""" val = super(RegexConverter, self).to_url(value) return val#添加到flask中_ters['regex'] = RegexConverter@('/index/')def index(nid): print(url_for('index', nid='888')) return 'Index'if __name__ == '__main__': ()五、模板语⾔(防⽌xss攻击):django内有管道语⾔ mark_safe ,⽽ flask与之对应的是markup在flask内可以做块来完成 {% macro input(name, type='text', value='') %} {% endmacro %}六 、请求响应t相关1. @_requestrequest 顺序执⾏2. @_requestresponse 倒序执⾏3. 若拦截只拦截之后请求但不拦截响应4. 定制报错机制 #错误页⾯定制函数 @andler(404) def error_404(arg): return "不要瞎加url"5. 模板定制⽅法@te_global()def sb(a1, a2):return a1 + a2对应html: {{sb(1,2)}}@te_filter()def db(a1, a2, a3):return a1 + a2 + a3对应html:{{ 1|db(2,3)}}最常⽤@_request@_request⽩名单七、session 服务端 保存⽅式 回写 cookie加密——————————————————————————————————————1.装饰器 还需引⽤ functools 防⽌之后修饰的函数函数名不变,同时防⽌之后函数名重复这样就可以不⽤ endpoint import functools def wapper(func): @(func) #帮助我们设置函数的元信息 def inner(*args,**kwargs):

return func(*args,**kwargs) return inner

——————————————————————————————————————设置:session[‘username’] = ‘xxx’删除:(‘username’, None)其中⽤法_key = ‘sdfsdf’ def ... session[k1] = 'v1' session[k2] = 'v2'ps:要弄清楚的事情:1.路由中的装饰器 应放在什么地⽅ 放函数多了为什么会报错 因为重名给⽤户认证做装饰器-#装饰器-urlmethodendpoint url_for 反向⽣成 def wapper(func): def inner(*args,**kwargs): user = ('user_info') if not user: return redirect('/login') return func(*args,**kwargs) return inner同时应该在@ 的下⽅ 加@wapper ,但加到两个以上会出现重复报错 需要⽤ endpoint 进⾏重命名即可,如果加到上⽅的话相当于把下⾯的整体都装饰了。2. 制作脚本 对hosts 进⾏单⾏修改# -*- coding: utf-8 -*-#

防⽌命令⾏显⽰中⽂乱码import sysimport ospath = "⽂件路径"def add(ip , domain): #

在⽂件下增加内容 try: with open(path, 'a+') as text: for line in nes(): if ip + " "+ domain in line: print("已经存在") break ("n"+ ip + " "+ domain) except: print("添加出错")def delete(ip , domain): with open(path) as text, open('', "w") as new_text: try: for line in nes(): new_line = e("n"+ip + " "+ domain, "") new_(new_line) except: print("删除出错") (path) ("", "⽂件名")

if __name__ == '__main__': command = [1].lower() #

参数⼀ ip = [2] #

参数⼆ domain = [3] #

参数三

if command == "add": add(ip, domain) elif command == "del": delete(ip, domain) else: print("没有此命令")⼋、闪现-a页⾯报错category 的使⽤是防⽌信息错乱的 p20课讲到category=“x1”get_flashed_messages(category_filter=[‘x1’])应⽤:对临时信息操作 ⽤session也可⽤到 typedata九、蓝图 ⽂件归类 框架类似于:-- ⽂件夹 – __init__⽂件 – from import – 然后还要调⽤如同代理 分发blueprint蓝图URL前缀:xxx = Blueprint(‘account’, name,url_prefix=’/xxx’)可⽤ template_folder 来进⾏指定位置寻找html构造程序⽬录-批量url-模板路径、静态⽂件路径-请求扩展针对app针对摸个蓝图选择1个应⽤ :⼩型 ⼀般⽤这个 到后⾯不好拆分 视图函数不要重复 加前缀bluen个应⽤: ⼤型⼗、请求扩展 装饰器 与dijango中间件相同在请求已经解释⼗⼀、中间件 项⽬开始之前定制功能⽤wsgi-#请求之后之前定制⼀些操作

class MiddleWare: def __init__(self,wsgi_app): _app = wsgi_app

def __call__(self, *args, **kwargs):

return _app(*args, **kwargs)

if __name__ == "__main__": _app = MiddleWare(_app) (port=9999)

⼗⼆、上下⽂管理(重要核⼼)Local 本地线程源码 (request)-多线程操作⼀个值- 锁import threadinglocal_values = 完成线程分配

为每⼀块线程开辟⼀块空间保存它独有的值多线程不能是全局变量 ⽤local就可以⽀持多线程单进程单线程(多个协程),对象不⾏ -决定 - 不⽀持协程: 实现并发操作 - ⽀持:⾃定义对象 ⽀持协程

get_ident() 获取线程的唯⼀标识

ps:

a. 初始设置: def __init__(self)

object.__setattr__(self,'storage',{})

或者 - e = {}

b.

对象.xx 触发条件 . def __setattr__(self,key,value): print(key,value)2.信号3.数据库连接池 单模式导致只能⼀个接⼝,所以就实现⼀个连接池 实现

1.上下⽂ * 前⼣: - 三个类 - environ - request 递归调⽤

-和 Flask⾃定义对象

- 请求到来 - ctx = 封装RequestContext(request,session) - ctxfangdao local中

- 执⾏视图时 - 导⼊ request相关 - print(request) localProxy对象的_str_ - localProxy对象的_getattr_ - request + 1 localProxy对象的_add_ - 调⽤ _lookup_req_object函数: 去local 中将requestContext中获得request或session

-请求结束 —— _pop() - ctx从local 中移除

2.数据库连接池: django :ORM Flask 其他 -原⽣sql - pymysql 主要点 - mysqldb - sqlAchemy(ORM)#

原⽣sql:#单线程可⽤多线程不⾏import pymysql CONN = t(host='127.0.0.1', port=3306, user='root', password='123', database='pooldb', charset='utf8')

cursor = () #拿到游标 e('select*from tb1') result = ll() () print(result)并发量增⼤数据库崩溃解决⽅法:以下放⼊全局变量CONN = t(host='127.0.0.1', port=3306, user='root', password='123', database='pooldb', ----函数内 创建⼀定量的连接池 4.使⽤DBUtils来完成 创建⼀定量的连接池 [专门介绍DBUtils使⽤] (/wupeiqi/articles/tps:///wupeiqi/articles/)

模式⼀:为每个线程创建连接 模式⼆:创建n个连接,多线程来时,去获取。p37

class @staticmetheod def ....(sql,args)

conn = tion(shareable=False) cursor = () e('select * from tb1') result = ll() () ()

ps:sqlhelper4.流程图上下⽂⾯向对象:私有字段:_类名__私有函数名- 与django相⽐是两种不同的实现⽅式- django tornado 是通过传参形式- flask是通过上下⽂管理两种都可以⼀⼀实现,只不过试⼀下⽅式不⼀样-上下⽂管理流程 - local类,创建字典 {greelet}做唯⼀标识 存数据 并保证数据隔离 - 请求进来 - 将请求相关数据封装到 requestcontext中 - 再将requestcontext对象添加到local中 通过localstack将对象添加到local对象中 - 使⽤ 调⽤request - 调⽤此类⽅法 、print(request)、request + xxx 会执⾏localproxy对应⽅法 - 函数 - 通过localstack去local中获取值

- 请求结束 - 通过localstack的pop⽅法 在local中将值移除5.请求上下⽂和应⽤上下⽂a.请求上下⽂requestsessionb.应⽤上下⽂请求流程:1.请求到来,有⼈能访问将请求相关数据 environ 封装到 requestcontext对象中再将对象封装到local中 every线程 名称t 封装请求相关东西n_request_ctx_ = { 唯⼀标识:{ “stack”:[ctx,] } }_app_ctx_ = { 唯⼀标识:{ “stack”:[app_ctx,] } }

2.使⽤from flask import request,session,g,current_appprint(request,session,g,current_app)都执⾏相应 localpproxy对象的

str3.终⽌,全部pop多线程是获取唯⼀标识的作⽤,那保存数据为什么使⽤栈?原因:当为 web程序时,栈只有⼀条可不⽤栈当为离线脚本 测试时 获取app信息,可能存在app上下⽂嵌套的关系此时就需要⽤到栈。ps:多app应⽤时打开关闭⼀般都可⽤到with

2023年8月3日发(作者:)

Flask学习笔记总结(⼀)Flask学习笔记总结(⼀)说明:开始在csdn上⾯记录⼀些关于⾃⼰学习技术的笔记总结。⽂章⽬录前⾔在IT⾏业中是需要不断去学习和拓展⾃⼰的知识⾯的,只有不断接触新知识才能不断提⾼⾃⼰的能⼒和价值,我相信没有知识是⽩学的,希望⾃⼰能成为⼀个好的程序员。提⽰:个⼈学习随笔,⾃⼰记录使⽤,仅供参考⼀、python的web三⼤框架:重武器 组件超多 便捷 例 ORM FORM modelform 缓存 session2. Flask: 短⼩精悍 第三⽅组件较为丰富 开发⼩的⽤flask,路由较为特殊:基于装饰器实现,但究其本质还是通过add_url_rule来实现.conf 为配置⽂件3. Tornado:异步⾮阻塞框架() 1线程跑 1000个任务⼆、flask⼊门对于Werkzeug本质是Socket服务端,其⽤于接收http请求并对请求进⾏预处理,然后触发Flask框架本质Werkzeug⽰例:代码如下:from rs import Request, Response@ationdef hello(request): return Response('Hello World!')if __name__ == '__main__': from g import run_simple run_simple('localhost', 4000, hello) # 看到run_simple代表socket执⾏ 监听端⼝代码如下(⽰例):from flask import Flask#实例化flask对象app = Flask(__name__) ###将'/'和 index的对应关系添加到路由器中"""{ '/':index}"""@('/') #装饰器 两步 相当于 先执⾏ v=('/') 再执⾏ v()#def hello_world(): return 'Hello World!'

if __name__ == '__main__': # 监听⽤户请求 #如果有请求 则执⾏app的__call__⽅法 () #运⾏ 等待连接 与run_simple有关联3.⽤户demo1.登录界⾯(主程序)代码如下(⽰例):from flask import Flask,render_template,request,redirect#render_template是表⽰页⾯模板 request请求相关全放⼊⾥⾯# 实例化flask对象app = Flask(__name__)@('/login',methods=['GET',"POST"]) # 装饰器 两步 相当于 先执⾏ v=('/') 再执⾏ v()def index(): if == "GET": return render_template('') else: user = ('user') pwd = ('pwd') if user == 'lixuan' and pwd == '123': return redirect('') return render_template('',error='⽤户名或密码错误')# url的所有数据都在query_string内if __name__ == '__main__': # 监听⽤户请求 # 如果有请求 则执⾏app的__call__⽅法 () # 运⾏ 等待连接 与run_simple有关联2.⽹页程序() Title

⽤户登录

{{error}}
3.⽤户列表展⽰装饰器:⽤户认证装饰器demo代码如下:def wrapper(func) def inner(*arg,**kwargs) return func(*arg,**kwargs) return inner@wrapper #执⾏wrapper并将下⾯当参数 index=wrapper(index)def index(request): pass

登录函数内:session[‘user_info’] = user外函数判断(弃⽤了):user = ('user_info') if not user: url = url_for('l1') return redirect(url)三、配置⽂件:设置⽅法1 [‘DEBUG’] = True设置⽅法2 = True-设置⽅法2 = True设置⽅法3 最规范直接做⼀个 然后去调⽤即可main⽂件: _object(“python类或类的路径”)例: _object(‘pro_gConfig’)内的类:class TestingConfig(Config):—— TESTING = Trueps:知识点django rest frameworkdjango 中间件需求:cpu占⽤90%,发送警报:邮件。。。。数据库操作:mysql。。。。缓存放在redis/memcache 调换使⽤ 可以放在配置⽂件去if else四、路由系统 需要扩展 (diango可直接实现):1.代码如下:def route(self, rule, **options):

def decorator(f): endpoint = ('endpoint', None) _url_rule(rule, endpoint, f, **options) #add_url_rule加到路由表中 return f return decoratordef

可⽀持cbv 层层嵌套继承url重定向 、 为保留原地址可⽤ : redirect_to="/新地址后缀“subdomain=None #代表域名前部2. 域名变化@("/dynamic", subdomain="")def username_index(username): """Dynamic subdomains are also supported Try going to /dynamic""" return username + "."

ps : c-window-system32-drivers-etc-hosts 修改域名,测试⼈员常⽤

username : 字符串int:post_id :整型3.正则表达式需进⾏⾃制创建类 class RegexConverter(BaseConverter):

""" ⾃定义URL匹配正则表达式 """ def __init__(self, map, regex): super(RegexConverter, self).__init__(map) = regex def to_python(self, value): """ 路由匹配时,匹配成功后传递给视图函数中参数的值 :param value:

:return:

""" return int(value) #格式检测转换 def to_url(self, value): """ 使⽤url_for反向⽣成URL时,传递的参数经过该⽅法处理,返回的值⽤于⽣成URL中的参数 :param value:

:return:

""" val = super(RegexConverter, self).to_url(value) return val#添加到flask中_ters['regex'] = RegexConverter@('/index/')def index(nid): print(url_for('index', nid='888')) return 'Index'if __name__ == '__main__': ()五、模板语⾔(防⽌xss攻击):django内有管道语⾔ mark_safe ,⽽ flask与之对应的是markup在flask内可以做块来完成 {% macro input(name, type='text', value='') %} {% endmacro %}六 、请求响应t相关1. @_requestrequest 顺序执⾏2. @_requestresponse 倒序执⾏3. 若拦截只拦截之后请求但不拦截响应4. 定制报错机制 #错误页⾯定制函数 @andler(404) def error_404(arg): return "不要瞎加url"5. 模板定制⽅法@te_global()def sb(a1, a2):return a1 + a2对应html: {{sb(1,2)}}@te_filter()def db(a1, a2, a3):return a1 + a2 + a3对应html:{{ 1|db(2,3)}}最常⽤@_request@_request⽩名单七、session 服务端 保存⽅式 回写 cookie加密——————————————————————————————————————1.装饰器 还需引⽤ functools 防⽌之后修饰的函数函数名不变,同时防⽌之后函数名重复这样就可以不⽤ endpoint import functools def wapper(func): @(func) #帮助我们设置函数的元信息 def inner(*args,**kwargs):

return func(*args,**kwargs) return inner

——————————————————————————————————————设置:session[‘username’] = ‘xxx’删除:(‘username’, None)其中⽤法_key = ‘sdfsdf’ def ... session[k1] = 'v1' session[k2] = 'v2'ps:要弄清楚的事情:1.路由中的装饰器 应放在什么地⽅ 放函数多了为什么会报错 因为重名给⽤户认证做装饰器-#装饰器-urlmethodendpoint url_for 反向⽣成 def wapper(func): def inner(*args,**kwargs): user = ('user_info') if not user: return redirect('/login') return func(*args,**kwargs) return inner同时应该在@ 的下⽅ 加@wapper ,但加到两个以上会出现重复报错 需要⽤ endpoint 进⾏重命名即可,如果加到上⽅的话相当于把下⾯的整体都装饰了。2. 制作脚本 对hosts 进⾏单⾏修改# -*- coding: utf-8 -*-#

防⽌命令⾏显⽰中⽂乱码import sysimport ospath = "⽂件路径"def add(ip , domain): #

在⽂件下增加内容 try: with open(path, 'a+') as text: for line in nes(): if ip + " "+ domain in line: print("已经存在") break ("n"+ ip + " "+ domain) except: print("添加出错")def delete(ip , domain): with open(path) as text, open('', "w") as new_text: try: for line in nes(): new_line = e("n"+ip + " "+ domain, "") new_(new_line) except: print("删除出错") (path) ("", "⽂件名")

if __name__ == '__main__': command = [1].lower() #

参数⼀ ip = [2] #

参数⼆ domain = [3] #

参数三

if command == "add": add(ip, domain) elif command == "del": delete(ip, domain) else: print("没有此命令")⼋、闪现-a页⾯报错category 的使⽤是防⽌信息错乱的 p20课讲到category=“x1”get_flashed_messages(category_filter=[‘x1’])应⽤:对临时信息操作 ⽤session也可⽤到 typedata九、蓝图 ⽂件归类 框架类似于:-- ⽂件夹 – __init__⽂件 – from import – 然后还要调⽤如同代理 分发blueprint蓝图URL前缀:xxx = Blueprint(‘account’, name,url_prefix=’/xxx’)可⽤ template_folder 来进⾏指定位置寻找html构造程序⽬录-批量url-模板路径、静态⽂件路径-请求扩展针对app针对摸个蓝图选择1个应⽤ :⼩型 ⼀般⽤这个 到后⾯不好拆分 视图函数不要重复 加前缀bluen个应⽤: ⼤型⼗、请求扩展 装饰器 与dijango中间件相同在请求已经解释⼗⼀、中间件 项⽬开始之前定制功能⽤wsgi-#请求之后之前定制⼀些操作

class MiddleWare: def __init__(self,wsgi_app): _app = wsgi_app

def __call__(self, *args, **kwargs):

return _app(*args, **kwargs)

if __name__ == "__main__": _app = MiddleWare(_app) (port=9999)

⼗⼆、上下⽂管理(重要核⼼)Local 本地线程源码 (request)-多线程操作⼀个值- 锁import threadinglocal_values = 完成线程分配

为每⼀块线程开辟⼀块空间保存它独有的值多线程不能是全局变量 ⽤local就可以⽀持多线程单进程单线程(多个协程),对象不⾏ -决定 - 不⽀持协程: 实现并发操作 - ⽀持:⾃定义对象 ⽀持协程

get_ident() 获取线程的唯⼀标识

ps:

a. 初始设置: def __init__(self)

object.__setattr__(self,'storage',{})

或者 - e = {}

b.

对象.xx 触发条件 . def __setattr__(self,key,value): print(key,value)2.信号3.数据库连接池 单模式导致只能⼀个接⼝,所以就实现⼀个连接池 实现

1.上下⽂ * 前⼣: - 三个类 - environ - request 递归调⽤

-和 Flask⾃定义对象

- 请求到来 - ctx = 封装RequestContext(request,session) - ctxfangdao local中

- 执⾏视图时 - 导⼊ request相关 - print(request) localProxy对象的_str_ - localProxy对象的_getattr_ - request + 1 localProxy对象的_add_ - 调⽤ _lookup_req_object函数: 去local 中将requestContext中获得request或session

-请求结束 —— _pop() - ctx从local 中移除

2.数据库连接池: django :ORM Flask 其他 -原⽣sql - pymysql 主要点 - mysqldb - sqlAchemy(ORM)#

原⽣sql:#单线程可⽤多线程不⾏import pymysql CONN = t(host='127.0.0.1', port=3306, user='root', password='123', database='pooldb', charset='utf8')

cursor = () #拿到游标 e('select*from tb1') result = ll() () print(result)并发量增⼤数据库崩溃解决⽅法:以下放⼊全局变量CONN = t(host='127.0.0.1', port=3306, user='root', password='123', database='pooldb', ----函数内 创建⼀定量的连接池 4.使⽤DBUtils来完成 创建⼀定量的连接池 [专门介绍DBUtils使⽤] (/wupeiqi/articles/tps:///wupeiqi/articles/)

模式⼀:为每个线程创建连接 模式⼆:创建n个连接,多线程来时,去获取。p37

class @staticmetheod def ....(sql,args)

conn = tion(shareable=False) cursor = () e('select * from tb1') result = ll() () ()

ps:sqlhelper4.流程图上下⽂⾯向对象:私有字段:_类名__私有函数名- 与django相⽐是两种不同的实现⽅式- django tornado 是通过传参形式- flask是通过上下⽂管理两种都可以⼀⼀实现,只不过试⼀下⽅式不⼀样-上下⽂管理流程 - local类,创建字典 {greelet}做唯⼀标识 存数据 并保证数据隔离 - 请求进来 - 将请求相关数据封装到 requestcontext中 - 再将requestcontext对象添加到local中 通过localstack将对象添加到local对象中 - 使⽤ 调⽤request - 调⽤此类⽅法 、print(request)、request + xxx 会执⾏localproxy对应⽅法 - 函数 - 通过localstack去local中获取值

- 请求结束 - 通过localstack的pop⽅法 在local中将值移除5.请求上下⽂和应⽤上下⽂a.请求上下⽂requestsessionb.应⽤上下⽂请求流程:1.请求到来,有⼈能访问将请求相关数据 environ 封装到 requestcontext对象中再将对象封装到local中 every线程 名称t 封装请求相关东西n_request_ctx_ = { 唯⼀标识:{ “stack”:[ctx,] } }_app_ctx_ = { 唯⼀标识:{ “stack”:[app_ctx,] } }

2.使⽤from flask import request,session,g,current_appprint(request,session,g,current_app)都执⾏相应 localpproxy对象的

str3.终⽌,全部pop多线程是获取唯⼀标识的作⽤,那保存数据为什么使⽤栈?原因:当为 web程序时,栈只有⼀条可不⽤栈当为离线脚本 测试时 获取app信息,可能存在app上下⽂嵌套的关系此时就需要⽤到栈。ps:多app应⽤时打开关闭⼀般都可⽤到with