详解Python的Flask框架中的signals信号机制
Flask 提供了信号(Signals)功能,是一种消息分发机制。类似于钩子(Hooks)。使用信号功能可以降低程序的耦合,分解复杂的业务模型。例如在更新了产品数据后,可以发送一个信号。当有需要对产品数据进行处理的功能时,就可以捕获信号进行处理。比如要建立产品缓存,或是更新搜索索引等。 定义信号 Flask 信号功能使用了 Blinker 模块,所以需要先安装 Blinker 模块 pip install blinker 定义一个信号: from blinker import Namespace product_saved = Namespace() 也可以使用 Flask 包装的 singles 对象: from flask.singles import Namespace 发送信号 发送信号需要带上 app 实例方法,示例如下: product_saved.send(app,product=product) app 后面可以添加要传递的参数,但必须以 name=value 的格式,不支持使用单个变量名的方式。 收接信号 接收信号可以使用 connect_via 装饰器函数: @product_saved.connect_via(app) def updateCache(app,product): print(product) Flask 中有以下核心信号: 1.flask.template_rendered 这个信号发送于一个模板被渲染成功后。信号传递的template是模板的实例,context是环境对象是一个字典。 订阅示例: def log_template_renders(sender,template,context,**extra): sender.logger.debug('Rendering template "%s" with context %s',template.name or 'string template',context) from flask import template_rendered template_rendered.connect(log_template_renders,app) 2.flask.request_started 这个信号发送于请求开始之前,且请求环境设置完成之后。因为请求环境已经绑定, 所以订阅者可以用标准的全局代理,如 request 来操作请求。 订阅示例: def log_request(sender,**extra): sender.logger.debug('Request context is set up') from flask import request_started request_started.connect(log_request,app) flask.request_finished 这个信号发送于向客户端发送响应之前。信号传递的response为将要发送的响应。 订阅示例: def log_response(sender,response,**extra): sender.logger.debug('Request context is about to close down. ' 'Response: %s',response) from flask import request_finished request_finished.connect(log_response,app) flask.got_request_exception 这个信号发送于请求进行中发生异常的时候。它的发送 早于 标准异常处理介于。 在调试模式下,虽然没有异常处理,但发生异常时也发送这个信号。信号传递的exception是异常对象。 订阅示例: def log_exception(sender,exception,**extra): sender.logger.debug('Got exception during processing: %s',exception) from flask import got_request_exception got_request_exception.connect(log_exception,app) flask.request_tearing_down 这个信号发送于请求崩溃的时候,不管是否引发异常。目前,侦听此信号的函数在一般 崩溃处理器后调用,但是没有什么东西可用。 订阅示例: def close_db_connection(sender,**extra): session.close()from flask import appcontext_tearing_down request_tearing_down.connect(close_db_connection,app) 在 Flask 版本 0.9 中,这还会传递一个exc关键字参数,如果这个参数存在的话。 这个参数是引发崩溃的异常的引用。 3.flask.appcontext_tearing_down 当应用环境崩溃时发送这个信号。这个信号总是会发送,甚至是因为一个异常引发的 崩溃。侦听这个信号的函数会在常规崩溃处理器后被调用,但是你无法回馈这个信号。 订阅示例: def close_db_connection(sender,**extra): session.close()from flask import request_tearing_down appcontext_tearing_down.connect(close_db_connection,app) 这还会传递一个exc关键字参数,如果这个参数存在的话。这个参数是引发崩溃的 异常的引用。 4.flask.appcontext_pushed 当一个应用的环境被压入时,应用会发送这个信号。这个信号通常用于在单元测试中 临时钩接信息。例如可以用于改变g对象中现存的资源。 用法示例: from contextlib import contextmanagerfrom flask import appcontext_pushed @contextmanagerdef user_set(app,user): def handler(sender,**kwargs): g.user = user with appcontext_pushed.connected_to(handler,app): yield 在测试代码中这样写: def test_user_me(self): with user_set(app,'john'): c = app.test_client() resp = c.get('/users/me') assert resp.data == 'username=john' New in version 0.10. 5.appcontext_popped 当一个应用的环境被弹出时,应用会发送这个信号。这个信号通常写成appcontext_tearing_down 信号。 6.flask.message_flashed 当应用闪现一个消息时会发出这个信号。message`参数是消息内容, `category参数是消息类别。 订阅示例: recorded = []def record(sender,message,category,**extra): recorded.append((message,category)) from flask import message_flashed message_flashed.connect(record,app) 小结 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |