session._get_current_object()完全返回什么对象? [英] What object EXACTLY is returned by session._get_current_object()?

查看:179
本文介绍了session._get_current_object()完全返回什么对象?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在和Flask一起玩,努力了解会话如何工作的详细信息,我正在使用:

  • Python 3.6.1
  • 烧瓶0.12.2

烧瓶文档明确声明(粗体为我的):

会话对象的工作原理与普通字典非常相似, 跟踪修改的不同之处.

这是代理.

...

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

如果您需要访问 到被代理的基础对象,您可以使用 _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应用程序,并反复进入/,则session._get_current_object()返回的ID有时会更改,而threading.current_thread().ident则永远不会更改.

这使我提出以下问题:

  1. session._get_current_object()返回的是什么恰好?
  2. 我得到的是它是session代理的基础对象,但是该基础对象所绑定的对象(对于简单应用程序,如果不是请求而不是线程,那么我希望它永远不会改变)以上)?

解决方案

session._get_current_object()到底返回什么?

从技术上讲,它是 RequestContext Flask.wsgi_app 中实例化的a>,
RequestContext实现往返于本地堆栈_request_ctx_stackpushpop自身的方法. push方法还处理请求新会话.

此会话是session代理中可用的会话;通过request代理可以使用初始化RequestContext的请求.这两个代理仅在请求上下文内可用,即正在处理活动的HTTP请求.

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

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

session._get_current_object()的ID在连续请求之间保持不变可能是由于在与先前请求中的旧会话对象所占用的内存地址相同的内存地址中创建了新的会话对象.

另请参见:上下文的工作原理 Flask文档中的部分.

I am playing around with Flask, striving to understand details of how sessions are working, I am using:

  • Python 3.6.1
  • Flask 0.12.2

Flask documentation clearly states (bold is mine):

The session object works pretty much like an ordinary dict, with the difference that it keeps track on modifications.

This is a proxy.

...

Section on proxies mentions that (again, bold is mine):

If you need to get access to the underlying object that is proxied, you can use the _get_current_object() method

Thus, underlying object (session._get_current_object()) must remain the same for the request or, as was suggested by this answer and comment, a thread. Though, it does not persist nor inside request, nor thread.

Here is a demonstration code:

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

If you will run Flask application above, and repeatedly go to the / — id returned by session._get_current_object() will, occasionally, change, while threading.current_thread().ident never changes.

This leads me to ask the following questions:

  1. What exactly is returned by session._get_current_object()?
  2. I get that it is an object underlying session proxy, but what this underlying object is bound to (if it is not a request and not a thread, if anything I would expect it never to change, for the simple application above)?

解决方案

What exactly is returned by session._get_current_object()?

Technically speaking, it is the object referenced in the session attribute of the top-most element in the LocalStack instance named _request_ctx_stack.
This top-most element of that stack is a RequestContext that is instantiated in Flask.wsgi_app, which is called for every HTTP request.
The RequestContext implements methods to push and pop itself to and from the local stack _request_ctx_stack. The push method also takes care of requesting a new session for the context.

This session is what is made available in the session proxy; the request, that the RequestContext has been initialized with, is made available via the request proxy. These two proxies are only usable inside a request context, i.e. with an active HTTP request being processed.

I get that it is an object underlying session proxy, but what this underlying object is bound to (if it is not a request and not a thread, if anything I would expect it never to change, for the simple application above)?

As outlined above, the request context's session, proxied by the session local proxy, belongs to the RequestContext. And it is changing with every request. As documented in Lifetime of the Context, a new context is created for each request, and it creates a new session every time push is executed.

The id of session._get_current_object() staying the same between consecutive requests is, probably, due to the new session object being created in the same memory address that the old one from the previous request occupied.

See also: How the Context Works section of the Flask documentation.

这篇关于session._get_current_object()完全返回什么对象?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆