Python Flask 的 session 是全局的话,怎么避免变量传值重复(被覆盖)呢?

2017-03-23 11:13:31 +08:00
 rogwan

比如: session['yonghuming'] = request.form['username']

把表单中的 username 传给 session ,用 yonghuming 变量保存,下次可以用 session.get('yonghuming')把这个值取出来。

如果 session 是全局的话,再一些特殊情况下(比如,定时任务、异步认为中,前面存的 yonghuming 还没来得及读取,就被后面同样的 request.form['username']赋值给覆盖了。这怎么整?

另外,说 Flask 的 session 设计是 cookie based ,按理说,应该是每个用户的请求又应该算是非全局的,可以重名,不用担心被覆盖吧?

4214 次点击
所在节点    Python
11 条回复
ipwx
2017-03-23 11:26:03 +08:00
对于 session 变量本身,它是个 threading-local 变量,所以不会有多线程问题。

而且 Python 除了 PyPy 开不了多线程,整个 Python 进程就是个巨大的单线程程序。
cizixs
2017-03-23 11:27:29 +08:00
flask 中的 request 、 session 、 g 都是协程 /进程安全的。简单说,它们看似是全局变量,但其实每个请求的值都是单独保存的,不会相互影响。

如果想明白内部的实现,可以看这篇文章: http://cizixs.com/2017/01/13/flask-insight-context

另,迷之 `yonghuming` 变量。
rogwan
2017-03-23 11:30:17 +08:00
@ipwx 谢谢,按这个解释思路,如果 session['yonghuming'] = request.form['username'] 的'yonghuming'在 10 分钟之后取,但是中途在第 3 分钟的时候,被另外一个 form 又赋值了一次,那 10 分钟之后取的‘ yonghuming ’,其实是第 3 分钟复制的那个啦?
rogwan
2017-03-23 11:32:48 +08:00
@cizixs 是为了区分说清楚两个 username 呐,要体现出会用两种语言来命名的优势来~
ipwx
2017-03-23 11:33:51 +08:00
@rogwan 我觉得你对 Flask 的 session 有个误解。 Flask 的 session 是 cookie based ,所以每次请求都是从 cookie 里面抽出来的值,不存在服务器上。至于 cookie 是怎么维持的呢?

比如你某次请求让 flask 设置了一个 cookie ,服务器在送给客户端的 HTTP Header 里面会有一句

Set-Cookie: name=value .....(省略一些 cookie 的元信息)

然后下次浏览器发送给服务器的 HTTP Header 会带上:

Cookie: name=value

也就是说这来回传输的 HTTP 头维持了状态。

回到你的问题,每次 flask 处理某个请求, session 对象都是临时从 HTTP Header 里面重建出来的。 10 分钟之后是什么,这要看浏览器给你的是什么。
julyclyde
2017-03-23 11:53:06 +08:00
定时任务还有 request ?
est
2017-03-23 12:01:27 +08:00
这就是 Flask 最具特色、魅力和争议的黑魔法了。它的 request, session 不是一个普通对象。是一个逗比对象。
rogwan
2017-03-23 12:03:35 +08:00
@ipwx 谢谢,明白~ 需要换个方式处理这个数值了。

@julyclyde 你说的对,想到后来不会再有 request 了,值都取不到。
ke1e
2017-03-23 12:07:44 +08:00
Flask 的 session 是 ThreadLocal 的,每个用户都有一个自己的栈,所以数据不会混乱的
Kilerd
2017-03-23 13:20:57 +08:00
那你咋不对 request 的正确性进行怀疑呢??

骚年,深入了解下 flask 内部实现吧。 兼具了争议和赞美的一种表示方法
julyclyde
2017-03-23 15:46:00 +08:00
你可能混淆了 session 域和 application 域

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/349677

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX