Flask中的信号及其含义
信号
- 信号通过发送发生在核心框架的其他地方或 Flask 扩展的动作时的通知来帮助你解耦应用。简而言之,信号允许特定的发送端通知订阅者发生了什么
订阅信号
- 使用 connect() 方法来订阅信号。该函数的第一个参数是信号发出时要调用的函数,第二个参数可选,用于确定信号的发送端。
- 使用 disconnect() 方法来退订。
- 对于所有的核心 Flask 信号,发送端都是发送信号的应用。当你订阅一个信号,请确保也提供一个发送端,除非你确实想监听全部应用的信号。这在你开发一个扩展的时候尤其正确。
创建信号
- 在定义的 Namespace 中命名信号。这也是大多时候推荐的做法:
1 | from blinker import Namespace |
-创建信号:
1 | model_saved = mysignals.signal('model-saved') |
- 这里使用唯一的信号名,简化调试。可以用 name 属性来访问信号名。
发送信号
- 调用 send() 方法,发出信号。 它接受发送端作为第一个参数,和一些推送到信号订阅者的可选关键字参数:
1 | class Model(object): |
-
永远尝试选择一个合适的发送端。如果你有一个发出信号的类,把 self 作为发送端。如果你从一个随记的函数发出信号,把
current_app._get_current_object()
作为发送端。 -
传递代理作为发送端: 永远不要向信号传递 current_app 作为发送端,使用
current_app._get_current_object()
作为替代。这样的原因是, current_app 是一个代理,而不是真正的对象。
信号与 Flask 的请求上下文
- 信号在接收时,完全支持请求上下文。上下文本地的变量在 request_started 和 request_finished 一贯可用,所以你可以信任 flask.g 和其他需要的东西。
基于装饰器的信号订阅
- 可以在 Blinker 1.1 中容易地用新的 connect_via() 装饰器订阅信号:
1 | from flask import template_rendered |
核心信号
flask.template_rendered
:模板渲染成功的时候发送,这个信号与模板实例template
、上下文的字典一起用。
1 | def log_template_renders(sender, template, context, **extra): |
flask.request_started
:建立请求上下文后,在请求处理开始前发送,订阅者可以用 request 之类的标准全局代理访问请求。
1 | def log_request(sender, **extra): |
flask.request_finished
:在响应发送给客户端之前发送,可以传递 response 。
1 | def log_response(sender, response, **extra): |
flask.got_request_exception
:在请求处理中抛出异常时发送,异常本身会通过 exception 传递到订阅的函数。
1 | def log_exception(sender, exception, **extra): |
flask.request_tearing_down
:在请求销毁时发送,它总是被调用,即使发生异常。
1 | def close_db_connection(sender, **extra): |
flask.appcontext_tearing_down
:在应用上下文销毁时发送,它总是被调用,即使发生异常。
1 | def close_db_connection(sender, **extra): |
flask.appcontext_pushed
: 这个信号在应用上下文压入栈时发送。发送者是应用对象。这通常在单元测试中为了暂时地钩住信息比较有用。例如这可以用来提前在 g 对象上设置一些资源。
1 | from contextlib import contextmanager |
flask.appcontext_popped
: 这个信号在应用上下文弹出栈时发送。发送者是应用对象。这通常在 appcontext_tearing_down 信号发送后发送flask.message_flashed
: 这个信号在应用对象闪现一个消息时发送。消息作为 message 命名参数发送,分类则是 category 参数。
1 | recorded = [] |