Python Flask 的 session 是全局的,如何避免变量传值重复或被覆盖?
比如: session['yonghuming'] = request.form['username']
把表单中的 username 传给 session ,用 yonghuming 变量保存,下次可以用 session.get('yonghuming')把这个值取出来。
如果 session 是全局的话,再一些特殊情况下(比如,定时任务、异步认为中,前面存的 yonghuming 还没来得及读取,就被后面同样的 request.form['username']赋值给覆盖了。这怎么整?
另外,说 Flask 的 session 设计是 cookie based ,按理说,应该是每个用户的请求又应该算是非全局的,可以重名,不用担心被覆盖吧?
Python Flask 的 session 是全局的,如何避免变量传值重复或被覆盖?
对于 session 变量本身,它是个 threading-local 变量,所以不会有多线程问题。
而且 Python 除了 PyPy 开不了多线程,整个 Python 进程就是个巨大的单线程程序。
Flask的session是基于cookie的客户端session,每个用户独立,但如果你指的是全局变量或模块级变量被多个请求共享导致的问题,那确实需要注意。
Flask应用在多线程/多worker环境下运行时,全局变量会被所有请求共享。比如你在模块层面定义了一个列表,所有用户请求都可能修改它,这肯定会导致数据混乱。
解决方案:
-
使用Flask的
g对象:针对单个请求的生命周期存储数据,请求结束后自动清理。from flask import g, request [@app](/user/app).before_request def set_user(): g.user_id = request.args.get('user_id') -
使用请求上下文:通过
request对象传递数据,每个请求都有独立的request对象。 -
彻底避免模块级可变全局变量:如果必须用全局状态,考虑使用线程安全的存储,比如:
from threading import Lock user_data = {} data_lock = Lock() def update_user_data(user_id, data): with data_lock: user_data[user_id] = data -
使用数据库或Redis:持久化存储用户数据,这是最可靠的方式。
关键点:Flask的session本身是用户隔离的,问题通常出在你自己定义的全局变量上。确保请求相关的数据要么放在g/request里,要么用用户ID作为键存储在字典中。
总结:用g对象或请求上下文替代全局变量。
flask 中的 request 、 session 、 g 都是协程 /进程安全的。简单说,它们看似是全局变量,但其实每个请求的值都是单独保存的,不会相互影响。
如果想明白内部的实现,可以看这篇文章: http://cizixs.com/2017/01/13/flask-insight-context 。
另,迷之 yonghuming 变量。
谢谢,按这个解释思路,如果 session[‘yonghuming’] = request.form[‘username’] 的’yonghuming’在 10 分钟之后取,但是中途在第 3 分钟的时候,被另外一个 form 又赋值了一次,那 10 分钟之后取的‘ yonghuming ’,其实是第 3 分钟复制的那个啦?
是为了区分说清楚两个 username 呐,要体现出会用两种语言来命名的优势来~
定时任务还有 request ?
这就是 Flask 最具特色、魅力和争议的黑魔法了。它的 request, session 不是一个普通对象。是一个逗比对象。
谢谢,明白~ 需要换个方式处理这个数值了。
你说的对,想到后来不会再有 request 了,值都取不到。
Flask 的 session 是 ThreadLocal 的,每个用户都有一个自己的栈,所以数据不会混乱的
那你咋不对 request 的正确性进行怀疑呢??
骚年,深入了解下 flask 内部实现吧。 兼具了争议和赞美的一种表示方法
你可能混淆了 session 域和 application 域


