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

在学习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伐。

모든 응답(2)
PHPzhong

이 질문의 핵심은 밑에서 세 번째 문장에 있습니다.

으아악

여기서 별도의 스레드가 개설되어 있는데 왜 스레드를 개설한 후 current_app를 사용할 수 없는지 궁금하실 수 있습니다. 오른쪽! 스레드를 열면 current_app을 사용할 수 없습니다. 그 이유는 current_app의 구현에 있습니다.

current_appFlask의 프록시입니다. Flask의 소스 코드를 보면 실제로 다음과 같이 래핑되어 있는 것을 알 수 있습니다.
소스 코드 주소 줄: 48-58

으아악

LocalProxy에 대해 자세히 설명하지는 않겠지만, 이 LocalProxy의 기능은 스레드/코루틴에 따라 현재 코루틴/스레드에 해당하는 객체를 반환하는 것이라고 말씀드릴 수 있습니다.

라고 말하다
  • 스레드 A가 A

  • 를 LocalProxy에 삽입합니다.
  • 스레드 B가 B를 LocalProxy에 삽입

어디에 있든

  • 스레드 A는 항상 A를 얻고, 스레드 B는 항상 B를 얻습니다.

이것이 Flask, request 같은 변수를 current_app의 코드에서 직접 사용할 수 있는 근본적인 이유입니다.

그래서 답은 이렇습니다. 여기서 새 스레드가 열리기 때문에 실제 개체를 통과하지 않으면 스레드에서 current_app를 사용하면 개체를 가져올 수 없습니다. flask 上下文이 없습니다. 이것은 Flask의 또 다른 중요한 개념이므로 할 말이 너무 많습니다.

질문하는 사람이 이해할 수 있어야 한다고 할 수 있습니다.

伊谢尔伦

당시 이 코드를 보고 똑같다고 생각했는데 app=current_object는 왜 안되나요?

다시 한번 살펴보세요. 내 요점은 문서의 설명에서 current_app이 전역 애플리케이션 객체이고 current_app._get_current_object가 get 객체(객체 가져오기)라고 언급하고 있다는 것입니다. 이는 다음 클래스 Staticmethod 및 classmethod에 해당합니다. (이 비유는 정확하지는 않지만 내가 의미하는 바를 이해하는 것은 어렵지 않습니다. 본질적으로 매우 유사합니다).

이 답변에 대한 설명 보기:

그러나 이렇게 말하는 것은 잘못된 것입니다.

현재 개체를 반환합니다. 이는 성능상의 이유로 한 번에 프록시 뒤의 실제 개체를 원하거나 개체를 다른 컨텍스트로 전달하려는 경우에 유용합니다.

여기에 적힌 것은 실물이다
이것이 인스턴스라는 뜻인가요? 이렇게 이해될 수도 있고, 물론 더 정확할 수도 있습니다.

무엇이든 상관없으니 소스코드를 보는 것이 낫습니다. 프레임워크를 설계한 사람이 역으로 작성하면 됩니다.
인스턴스인지 아닌지. 결국 코드도 사람이 디자인하고, 이 프레임워크도 사람이 작성하는 것이기 때문에 너무 집착하는 것은 의미가 없습니다. 객체든 인스턴스든 결국 둘 다 아니라고 생각하기 때문입니다.

최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿