猿问

session._get_current_object() 究竟返回了什么对象?

我正在玩 Flask,努力了解会话如何工作的细节,我正在使用:

  • Python 3.6.1

  • 烧瓶 0.12.2

Flask 文档清楚地说明粗体是我的):

session 对象的工作方式与普通的 dict 非常相似,不同之处在于它跟踪修改。

这是一个代理

...

关于代理的部分提到(再次,粗体是我的):

如果您需要访问被代理的底层对象,您可以使用该 _get_current_object()方法

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! ;-)'

如果你将运行上面的 Flask 应用程序,并反复转到will/返回的session._get_current_object()--id,偶尔会更改,而threading.current_thread().ident从不更改。

这导致我提出以下问题:

  1. 究竟返回的是什么session._get_current_object()

  2. 我知道它是一个对象底层session代理,但是这个底层对象绑定到什么(如果它不是请求而不是线程,如果有什么我希望它永远不会改变,对于上面的简单应用程序)?


肥皂起泡泡
浏览 333回答 2
2回答

蝴蝶不菲

究竟返回的是session._get_current_object()什么?从技术上讲,它是在名为 的实例session中最顶层元素的属性中引用的对象。 该堆栈的最顶层元素是在中实例化的a,每个 HTTP 请求都会调用它。与本地堆栈之间的实现方法及其自身。该方法还负责为上下文请求新会话。LocalStack_request_ctx_stackRequestContextFlask.wsgi_appRequestContextpushpop_request_ctx_stackpush这个会话是在session代理中可用的;RequestContext已初始化的请求可通过request代理获得。这两个代理只能在请求上下文中使用,即处理活动的 HTTP 请求。我知道它是一个对象底层会话代理,但是这个底层对象绑定到什么(如果它不是请求而不是线程,如果有什么我希望它永远不会改变,对于上面的简单应用程序)?如上所述,由session本地代理代理的请求上下文会话属于RequestContext. 它随着每个请求而变化。如上下文生命周期中所述,为每个请求创建一个新上下文,并且每次push执行时都会创建一个新会话。在连续请求之间保持相同的 idsession._get_current_object()可能是由于新会话对象创建在与前一个请求中的旧会话对象所占用的内存地址相同的内存地址中。另请参阅: Flask 文档的上下文如何工作部分。

慕容森

这是修改后的代码片段,以说明shmee的答案import threadingfrom flask import (Flask,session,request)app = Flask(__name__)app.secret_key = 'some random secret key'@app.route('/')def index():&nbsp; &nbsp; print(">>> session <<<")&nbsp; &nbsp; session_id = id(session)&nbsp; &nbsp; session_object_id = id(session._get_current_object())&nbsp; &nbsp; print("ID: {}".format(session_id),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Same as previous: {}".format(session.get('prev_sess_id', '') == session_id))&nbsp; &nbsp; print("_get_current_object() ID: {}".format(session_object_id),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Same as previous: {}".format(session.get('prev_sess_obj_id', '') == session_object_id))&nbsp; &nbsp; session['prev_sess_id'] = session_id&nbsp; &nbsp; session['prev_sess_obj_id'] = session_object_id&nbsp; &nbsp; print("\n>>> request <<<")&nbsp; &nbsp; request_id = id(request)&nbsp; &nbsp; request_object_id = id(request._get_current_object())&nbsp; &nbsp; print("request ID is: {}".format(request_id),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Same as previous: {}".format(session.get('prev_request_id', '') == request_id))&nbsp; &nbsp; print("request._get_current_object() ID is: {}".format(id(request._get_current_object())),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Same as previous: {}".format(session.get('prev_request_obj_id', '') == request_object_id))&nbsp; &nbsp; session['prev_request_id'] = request_id&nbsp; &nbsp; session['prev_request_obj_id'] = request_object_id&nbsp; &nbsp; print("\n>>> thread <<<")&nbsp; &nbsp; thread_id = threading.current_thread().ident&nbsp; &nbsp; print("threading.current_thread().ident is: {}".format(threading.current_thread().ident),&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; "Same as previous: {}".format(session.get('prev_thread', '') == thread_id))&nbsp; &nbsp; session['prev_thread'] = thread_id&nbsp; &nbsp; print('-' * 100)&nbsp; &nbsp; return 'Check the console! ;-)'实际上,唯一留下的模糊之处是为什么有时 session._get_current_object()在连续请求之间保持不变。正如shmee所建议的(粗体是我的),它是:可能是因为新会话对象是在与前一个请求中的旧会话对象占用的内存地址相同的内存地址中创建的。
随时随地看视频慕课网APP

相关分类

Python
我要回答