【问题标题】:Why is id of object returned by session._get_current_object() is changed on every request, while id of session remains unchanged?为什么 session._get_current_object() 返回的对象 id 在每次请求时都会更改,而 session 的 id 保持不变?
【发布时间】:2019-09-09 11:50:46
【问题描述】:

我正在使用:

  • Python 3.6.1
  • 烧瓶 0.12.2

Flask 文档的Section on session 说:

这是一个代理。

section on proxies 详细说明:

Flask 提供的一些对象是其他对象的代理。 这背后的原因是这些代理在 线程,它们必须分派到绑定到的实际对象 必要时在幕后穿线。
...
如果您需要访问 对于被代理的底层对象,您可以使用 _get_current_object()方法

这一切都非常简单。
但是当我尝试以下操作时:

from flask import (
Flask,
session,
)

app = Flask(__name__)
app.secret_key = 'some random secret key'

@app.route('/')
def index():
    print("session ID is: {}".format(id(session)))
    print("session._get_current_object() ID is: {}".format(id(session._get_current_object())))
    print('________________________________')

    return 'Check the console! ;-)'

每次我向/ 发出请求时,id(session._get_current_object()) 的值都不同,而id(session) 的值保持不变。

按照上面引用的Flask documentation,应该是相反的。那么为什么会这样呢?


更新
受到brunns 在 cmets 中对his answer 的建议的启发,即每个线程有一个底层对象

这是一些代码,用于测试每个线程有一个底层session 对象 (session._get_current_object()) 的假设:

import threading

from flask import (
Flask,
session,
)

app = Flask(__name__)
app.secret_key = 'some random secret key'

@app.route('/')
def index():
    print("session ID is: {}".format(id(session)))
    print("session._get_current_object() ID is: {}".format(id(session._get_current_object())))
    print("threading.current_thread().ident is: {}".format(threading.current_thread().ident))
    print('________________________________')
    return 'Check the console! ;-)'

尽管有预期,threading.current_thread().ident) 从未改变,而id(session._get_current_object() 正在改变。

【问题讨论】:

    标签: python python-3.x session flask request


    【解决方案1】:

    session 是您从flask 模块导入的对象。您只导入一次,它不会改变,id() 也不会改变。它在线程之间共享,并且是底层对象的代理。

    每个请求可能在不同的线程上运行,每个请求都有不同的底层对象,因此它们可能有不同的id()s。

    【讨论】:

    • 感谢您的回答。我想,我现在明白为什么id(session) 永远不会改变。虽然我仍然对session._get_current_object() 感到困惑。您能否详细说明以下内容:如果在每次请求后更改底层对象,session 正在代理什么?我的 (incorrect) 理解是 (?was) 是所有线程只有一个底层对象(在会话的生命周期内保持不变),session是该对象的代理。那么session._get_current_object() 返回的是什么?它也是一个代理对象吗(如果是,它代理到什么)?
    • 我的理解是有一个底层对象 ber 线程(不是每个请求),所以你会看到许多不同的 ids,但会有重复。除此之外,对不起,但你超出了我的知识范围!
    • 感谢您分享您的知识,它帮助我加深了对此事的理解。
    • 不过,我已经测试了 session._get_current_object() 是否与线程 ID 一起发生变化——但事实并非如此(参见我添加到问题中的示例)。
    • 代理会话对象是为每个请求创建的,因此它们的 id 应该是不同的。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多