【发布时间】:2019-04-24 11:06:53
【问题描述】:
在我对 Flask 会话的 another conundrum 进行调查期间,我试图更好地理解 Flask 会话的一般工作原理。
根据Flask documentation on sessions session 对象本身就是一个proxy。
我的理解(也就是说,很可能,在某种程度上是错误的,这就是这个问题的意义=)的意思是:
-
代理
session对象从应用程序访问,用于根据需要修改读取数据 -
通常,proxy-
session会立即将其更改转移到 proxied-session(除了 proxy-session中的 change of mutables) -
如果 proxied-
session忙(如果是多线程应用程序),proxy-session将等到 proxied-session可用,然后将其更改传输到 proxied-session -
模板接收“原始”会话(即代理-
session),因此没有能力/不需要从模板访问session._get_current_object() -
由于字典(
session是)是可变的,我假设它的 id 在会话期间应该保持不变(尽管可以修改内容) -
实际的
session(代理对象,可通过session._get_current_object()获得)永远不应更改其ID
现在,当我尝试检查我的假设时 - 我遇到的行为让我有点困惑。
考虑以下代码:
my_app.py
from flask import (
Flask,
render_template,
session,
)
app = Flask(__name__)
app.secret_key = 'some random secret key'
@app.route('/create/')
def create():
session['example'] = ['one', 'two']
print_ids()
return str(session['example'])
@app.route('/modify/')
def modify():
session['example'].append('three')
print_ids()
return render_template('my_template.html', id=id)
@app.route('/display/')
def display():
print_ids()
return str(session['example'])
def print_ids():
import inspect
calling_function = inspect.stack()[1][3]
print('')
print(calling_function + ": session ID is: {}".format(id(session)))
print(calling_function + ": session['example'] ID is {}".format(id(session['example'])))
print('________________________________')
print(calling_function + ": session._get_current_object() ID is: {}".format(id(session._get_current_object())))
print(calling_function + ": session._get_current_object()['example'] ID is: {}".format(id(session._get_current_object()['example'])))
my_template.html
<!doctype html>
<html>
<head><title>Display session['example']</title></head>
<body>
<div>
{% if session['example'] %}
{{ session['example'] }}
<br />
session ID is: {{ id(session) }}
<br />
session['example'] ID is: {{ id(session['example']) }}
<br />
{% else %}
session['example'] is not set =(
{% endif %}
</div>
</body>
</html>
这个想法是从每个函数,以及渲染模板上的id(session) 和id(session['example']),以便追踪在哪里使用了什么。
结果如下:
.../create/
# id(session) 4338311808
# id(session._get_current_object()) 4343709776
# id(session['example']) 4343654376
# id(session._get_current_object()['example']) 4343654376
.../modify/
# id(session) 4338311808
# id(session._get_current_object()) 4344315984
# id(session['example']) 4343652720
# id(session._get_current_object()['example']) 4343652720
rendered my_template.html
# id(session) 4344315984
# id(session['example']) 4343652720
.../display/
# id(session) 4338311808
# id(session._get_current_object()) 4344471632
# id(session['example']) 4341829576
# id(session._get_current_object()['example']) 4341829576
# one more time
.../display/
# id(session) 4338311808
# id(session._get_current_object()) 4344471632
# id(session['example']) 4344378072
# id(session._get_current_object()['example']) 4344378072
我正在努力理解的事情是:
-
关于 Flask 会话概念,我一般有哪些误解/错误假设?
-
为什么
session['example']和session._get_current_object()['example']的 id 在每次显示 时都会更改(以及其他所有方法,但特别是显示,因为它不会修改任何内容,我希望所有 id 都保持不变) ? -
为什么
session._get_current_object()的 id 发生变化而session的 id 不变? -
由于
session['example']和session._get_current_object()['example']的 id 在任何函数的上下文中都是相同的,我假设如果一个对象被更改 - 那么两者都被更改,因为它们是同一个对象。话虽如此,并考虑到
session._get_current_object()['example']是内部代理(即“真实”)session,我预计会出现以下情况:
.../create/ # return ['one', 'two']
.../modify/ # will render page containing ['one', 'two', 'three']
.../display/ # return ['one', 'two', 'three'] as proxy and proxied sessions should have been modified
但是作为I have previously discovered - 它没有发生。那么为什么 id 是一样的呢?
【问题讨论】:
标签: python session flask proxy