python - flask中current_app._get_current_object()与current_app有什么区别?
伊谢尔伦
伊谢尔伦 2017-04-17 17:59:56
0
2
1048

在学习flask开发,书中一段异步发送邮件的代码是这样写的:

from threading import Thread
from flask import current_app, render_template
from flask.ext.mail import Message
from . import mail


def send_async_email(app, msg):
    with app.app_context():
        mail.send(msg)


def send_email(to, subject, template, **kwargs):
    app = current_app._get_current_object()
    msg = Message(app.config['FLASKY_MAIL_SUBJECT_PREFIX'] + ' ' + subject,
                  sender=app.config['FLASKY_MAIL_SENDER'], recipients=[to])
    msg.body = render_template(template + '.txt', **kwargs)
    msg.html = render_template(template + '.html', **kwargs)
    thr = Thread(target=send_async_email, args=[app, msg])
    thr.start()
    return thr

send_mail函数中,程序使用了current_app._get_current_object()赋值给app作为当前程序的实例。此处为什么不直接使用current_app呢?

flask官方文档中是这样解释这个方法_get_current_object()的:

Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context.

看了这个我还是没懂书中的代码为什么要这样= =。。。

伊谢尔伦
伊谢尔伦

小伙看你根骨奇佳,潜力无限,来学PHP伐。

reply all(2)
PHPzhong

The key to this question lies in the third sentence from the bottom:

thr = Thread(target=send_async_email, args=[app, msg])

Because a separate thread is opened here, you may be wondering why the implementation of current_app 了?对!就是开了一个线程就不能使用 current_app。原因在于 current_app cannot be used when a thread is opened.

current_appFlask 是一个代理,如果你看 Flask If you look at the source code, you will find that it is actually wrapped like this:
Source code address line: 48-58

def _find_app():
    top = _app_ctx_stack.top
    if top is None:
        raise RuntimeError(_app_ctx_err_msg)
    return top.app

...

current_app = LocalProxy(_find_app)

The function of this LocalProxy 就不展开讲了,但是我可以告诉你这个LocalProxy is to return the object corresponding to the current coroutine/thread according to the thread/coroutine, that is to say

  • Thread A inserts A into LocalProxy

  • Thread B inserts B into LocalProxy

No matter where you are,

  • Thread A will always get A, thread B will always get B

This is the underlying reason for variables like Flask 中可以在代码中直接使用 requestcurrent_app.

So, here comes the answer, because a new thread is opened here, if you don't pass through the real object, then you use current_app 将获取不到对象,因为他没有 flask 上下文 inside the thread. This is another important concept of Flask, there is too much to say.

You can probably say this, and the questioner should be able to understand it.

伊谢尔伦

I saw this code at the time and thought it was the same, but why not app=current_object?

So take another look. My point is that the description in the document mentions that current_app is a global application object, and current_app._get_current_object is a get object (get an object), similar to the staticmethod and class below. classmethod corresponds to different things (this analogy is not accurate, but it is not difficult to get what I mean, they are essentially very similar).

Look at the explanation of this answer:

However, it is wrong to say this, look at the explanation of _get_current_object

Return the current object. This is useful if you want the real object behind the proxy at a time for performance reasons or because you want to pass the object into a different context.

What is written here is real object
Does this mean that this is an instance? It can be understood this way, and of course it can be more accurate.

Because no matter what, it’s better to look at the source code, because it doesn’t matter what it is. The person who designed the framework can write it in reverse and convert it
Whether it is an instance or an object, their methods will definitely be different. After all, the code is human Designed, this framework is also written by people. It has more to do with the framework itself. There is no more meaning in being too obsessed with objects or instances, because I guess in the end it is neither.

Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template