欢迎加入知了课堂,学习flask
Python Flask系列(1)——基础:http://study.163.com/course/courseMain.htm?courseId=1004091002
Python Flask框架——全栈开发: http://study.163.com/course/courseMain.htm?courseId=1004507006
本文介绍Flask中的信号机制,适合菜鸟入门理解
理解信号机制的概念以及应用
如何定义一个信号、订阅(监听)一个信号、发送一个信号
Flask内置的信号
一、什么是信号
什么是信号?信号通过发送发生在核心框架的其它地方或 Flask 扩展的动作 时的通知来帮助你解耦应用。简而言之,信号允许特定的发送端通知订阅者发 生了什么。
flask中文手册
其实这里的信号就是日常理解的信号,只是一种信息标号,它本身没有什么特殊含义。我们会事先约定好信号的的含义(定义信号)。通常我们说的监听信号,是服务器监听信号会什么时候发生;这里使用订阅是相对我们而言的(因为信号最终是要反映给我们人看的),像订阅公众号一样订阅信号,当这类信号发生时,我们知道发生了什么,那我们可以知道接下来该做什么了。而Flask信号(signals, or event hooking)允许特定的发送端通知订阅者发生了什么。
信号依赖于Blinker库
具体请参考手册:http://docs.pythontab.com/flask/flask0.10/signals.html
信号似乎和一些内置的 装饰器做同样的事(如:request_started 与 before_request() 十分相似)。然而它们工作的方式是有 差异的。
回顾一下之前学习的钩子函数(修饰器的一种):
Flask钩子(通常出现在蓝图或应用程序现存的方法中,比如一些内置装饰器,例如before_request
)不需要Blinker库并且允许你改变请求对象(request
)或者响应对象(response
)。这些改变了应用程序(或者蓝图)的行为。比如before_request()
装饰器。
信号看起来和钩子做同样的事情。然而在工作方式上它们存在不同。譬如核心的before_request()处理程序以特定的顺序执行,并且可以在返回响应之前放弃请求。相比之下,所有的信号处理器是无序执行的,并且不修改任何数据。
一般来说,钩子用于改变行为(比如,身份验证或错误处理),而信号用于记录事件(比如记录日志)。
二、flask中操作规范
2.1 定义信号
定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间,然后创建一个新信号。比如定义一个在访问了某个视图函数的时候的信号。
# Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题
from blinker import Namespace
zlspace = Namespace()
fire_signal = zlspace.signal('fire')
2.2 订阅信号
订阅(监听)信号使用singal对象的connect方法,在这个方法中需要传递一个函数,用来接收以后监听到这个信号该做的事情。
def fire_bullet(sender):
print(sender)
print('start fire bullet')
fire_signal.connect(fire_bullet)
2.3 发送信号
发送信号使用singal对象的send方法,这个方法可以传递一些其他参数过去。
fire_signal.send()
三、关于Flask内置的信号
1. template_rendered:模版渲染完成后的信号。
2. before_render_template:模版渲染之前的信号。
3. request_started:模版开始渲染。
4. request_finished:模版渲染完成。
5. request_tearing_down:request对象被销毁的信号。
6. got_request_exception:视图函数发生异常的信号。一般可以监听这个信号,来记录网站异常信息。
7. appcontext_tearing_down:app上下文被销毁的信号。
8. appcontext_pushed:app上下文被推入到栈上的信号。
9. appcontext_popped:app上下文被推出栈中的信号
10. message_flashed:调用了Flask的`flashed`方法的信号。
与自定义信号的使用方法一致
from flask import got_request_exception
def request_exception_log(sender,exception):
print(exception)
got_request_exception.connect(request_exception_log)
@app.route('/')
def hello_world():
a = 1/0
return render_template('index.html')
访问hello_world视图函数,服务器发出一个异常信号,再经过flask内置信号机制到request_exception_log()函数处理,打印异常信息!
参考文章:https://blog.csdn.net/mapleandkw/article/details/42492363
flask中文手册:http://docs.pythontab.com/flask/flask0.10/
欢迎加入知了课堂,学习flask
Python Flask系列(1)——基础:http://study.163.com/course/courseMain.htm?courseId=1004091002
Python Flask框架——全栈开发: http://study.163.com/course/courseMain.htm?courseId=1004507006