[关闭]
@buoge 2017-06-16T17:16:19.000000Z 字数 1963 阅读 1413

Flask 钩子和信号的区别

Python Flask


信号(signals)

Flask信号

Flask信号(signals, or event hooking)允许特定的发送端通知订阅者发生了什么( 既然知道发生了什么,那我们可以知道接下来该做什么了)。
Flask提供了一些信号(核心信号)且其它的扩展提供更多的信号。信号是用于通知 订阅者,而不应该鼓励订阅者修改数据。相关信号请查阅文档。
信号依赖于Blinker库。

系统信号详解

http://luciferlv.tech/2017/03/17/day0317/

钩子(hooks)

Flask钩子(通常出现在蓝图或应用程序现存的方法中,比如一些内置装饰器,例如 before_request)不需要Blinker库并且允许你改变请求对象(request)或者响应对 象(response)。这些改变了应用程序(或者蓝图)的行为。比如before_request() 装饰器。

信号看起来和钩子做同样的事情。然而在工作方式上它们存在不同。譬如核心的 before_request()处理程序以特定的顺序执行,并且可以在返回响应之前放弃请求 。相比之下,所有的信号处理器是无序执行的,并且不修改任何数据。

  1. from flask import Flask, g, request
  2. app = Flask(__name__)
  3. @app.before_request
  4. def before_request():
  5. print 'before request started'
  6. print request.url
  7. @app.before_request
  8. def before_request2():
  9. print 'before request started 2'
  10. print request.url
  11. g.name="SampleApp"
  12. @app.after_request
  13. def after_request(response):
  14. print 'after request finished'
  15. print request.url
  16. response.headers['key'] = 'value'
  17. return response
  18. @app.teardown_request
  19. def teardown_request(exception):
  20. print 'teardown request'
  21. print request.url
  22. @app.route('/')
  23. def index():
  24. return 'Hello, %s!' % g.name
  25. if __name__ == '__main__':
  26. app.run(host='0.0.0.0', debug=True)

栗子🌰

http://www.bjhee.com/flask-ad2.html

我们在全局定义了一个”index_called”信号对象,表示根路径被访问了。然后我们在根路径的请求处理中发出这个信号:

  1. from blinker import Namespace
  2. signals = Namespace()
  3. index_called = signals.signal('index-called')

  1. @app.route('/')
  2. def index():
  3. index_called.send(current_app._get_current_object(), method=request.method)
  4. return 'Hello Flask!'

发送信号消息的方法是”send()”,它必须包含一个参数指向信号的发送者。这里我们使用了”current_app._get_current_object()”来获取应用上下文中的app应用对象。怎么,忘了这个”current_app”是什么了?回顾下上一篇吧。这样每次客户端访问根路径时,都会发送”index_called”信号。”send()”方法可以有多个参数,从第二个参数开始是可选的,如果你要提供,就必须是key=value形式。而这个key就可以在订阅回调函数中接收。这个例子中,我们传递了请求的方法。


  1. def log_index_called(sender, method, **extra):
  2. print 'URL "%s" is called with method "%s"' % (request.url, method)
  3. index_called.connect(log_index_called, app)

将请求地址和方法打印在控制台上。

另外,同核心信号一样,自定义信号的回调函数也可以用装饰器来修饰,上面的代码等同于:

  1. @index_called.connect_via(app)
  2. def log_index_called(sender, method, **extra):
  3. print 'URL "%s" is called with method "%s"' % (request.url, method)
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注