为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

肥皂起泡泡 2022-01-18 21:27:05
我正在玩 Flask,努力了解会话如何工作的细节,我正在使用:Python 3.6.1烧瓶 0.12.2Flask 文档清楚地说明(粗体是我的):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从不更改。这导致我提出以下问题:究竟返回的是什么session._get_current_object()?我知道它是一个对象底层session代理,但是这个底层对象绑定到什么(如果它不是请求而不是线程,如果有什么我希望它永远不会改变,对于上面的简单应用程序)?
查看完整描述

2 回答

?
蝴蝶不菲

TA贡献1810条经验 获得超4个赞

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

从技术上讲,它是在名为 的实例session中最顶层元素的属性中引用的对象。 该堆栈的最顶层元素是在中实例化的a,每个 HTTP 请求都会调用它。与本地堆栈之间的实现方法及其自身。该方法还负责为上下文请求新会话。LocalStack_request_ctx_stack
RequestContextFlask.wsgi_app
RequestContextpushpop_request_ctx_stackpush

这个会话是在session代理中可用的;RequestContext已初始化的请求可通过request代理获得。这两个代理只能在请求上下文中使用,即处理活动的 HTTP 请求。

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

如上所述,由session本地代理代理的请求上下文会话属于RequestContext. 它随着每个请求而变化。如上下文生命周期中所述,为每个请求创建一个新上下文,并且每次push执行时都会创建一个新会话。

在连续请求之间保持相同的 idsession._get_current_object()可能是由于新会话对象创建在与前一个请求中的旧会话对象所占用的内存地址相同的内存地址中。

另请参阅: Flask 文档的上下文如何工作部分。


查看完整回答
反对 回复 2022-01-18
?
慕容森

TA贡献1853条经验 获得超18个赞

这是修改后的代码片段,以说明shmee的答案


import threading


from flask import (

Flask,

session,

request

)


app = Flask(__name__)

app.secret_key = 'some random secret key'


@app.route('/')

def index():

    print(">>> session <<<")

    session_id = id(session)

    session_object_id = id(session._get_current_object())

    print("ID: {}".format(session_id),

          "Same as previous: {}".format(session.get('prev_sess_id', '') == session_id))

    print("_get_current_object() ID: {}".format(session_object_id),

          "Same as previous: {}".format(session.get('prev_sess_obj_id', '') == session_object_id))

    session['prev_sess_id'] = session_id

    session['prev_sess_obj_id'] = session_object_id


    print("\n>>> request <<<")

    request_id = id(request)

    request_object_id = id(request._get_current_object())

    print("request ID is: {}".format(request_id),

          "Same as previous: {}".format(session.get('prev_request_id', '') == request_id))

    print("request._get_current_object() ID is: {}".format(id(request._get_current_object())),

          "Same as previous: {}".format(session.get('prev_request_obj_id', '') == request_object_id))

    session['prev_request_id'] = request_id

    session['prev_request_obj_id'] = request_object_id


    print("\n>>> thread <<<")

    thread_id = threading.current_thread().ident

    print("threading.current_thread().ident is: {}".format(threading.current_thread().ident),

          "Same as previous: {}".format(session.get('prev_thread', '') == thread_id))

    session['prev_thread'] = thread_id

    print('-' * 100)

    return 'Check the console! ;-)'

实际上,唯一留下的模糊之处是为什么有时 session._get_current_object()在连续请求之间保持不变。正如shmee所建议的(粗体是我的),它是:


可能是因为新会话对象是在与前一个请求中的旧会话对象占用的内存地址相同的内存地址中创建的。


查看完整回答
反对 回复 2022-01-18
  • 2 回答
  • 0 关注
  • 332 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
微信客服

购课补贴
联系客服咨询优惠详情

帮助反馈 APP下载

慕课网APP
您的移动学习伙伴

公众号

扫描二维码
关注慕课网微信公众号