flask中的信号机制
2019獨角獸企業重金招聘Python工程師標準>>>
flask中信號機制
Flask信號允許特定的發送端通知訂閱者發生了什么。既然知道發生了什么,那我們可以知道接下來該做什么了。Flask提供了一些信號(核心信號),其他擴展則提供了更多的信號。信號是用于通知訂閱者,而不是應該鼓勵訂閱者修改數據。信號依賴于Blinker庫,因此需要確保該庫已經安裝。信號處理器是無序執行的,并且不修改任何數據,主要用于記錄事件(比如記錄日志)。
創建信號:
如果你要在自己的應用中使用信號,你可以直接使用Blinker庫。最常見的使用情況是命名一個自定義的Namespace的信號。這也是大多數時候推薦的做法。
代碼如下:?
from?blinker?import?Namespace my_signals=Namespace() model_saved=my_signals.signal('model-saved')signal是Namespace類的函數,其原型是:signal(self,name,doc=None)? 返回一個信號對象。其實name參數是信號對象的名字,可以用name屬性來訪問信號名:model_saved.name。至此,信號已經創建好。
發送信號:
發送信號,可以通過調用send()方法來進行。send()函數原型是:send(self,*sender,**kwargs)。其中,sender是發送者,kwargs是可選參數。
代碼如下:
永遠嘗試選擇一個合適的發送者。如果你有一個發出信號的類,把self作為發送者。如果你從一個隨機的函數發出信號,把current_app._get_current_object()作為發送者。(不要把current_app作為發送者傳遞給信號。請使用current_app._get_current_object()。因為current_app是一個代理。不是實際的應用對象。)
訂閱信號:
使用信號的connect()方法可以訂閱該信號。該方法的原型是:connect(receiver,sender=ANY,weak=True)
?? receiver:信號發出時要調用的函數。
?? sender:該參數是可選的,用于確定信號的發送者。所有核心Flask信號的發送者是應用本身。因此當訂閱信號時請指定發送者,除非你真的想要收聽應用的所有信號。當你在開發一個擴展時,尤其要注意這點。
?? weak:如果是True,那么信號與接收者之間是弱引用。當接收者超出范圍或被垃圾回收時,信號與接收者自動斷開連接。
也可以使用disconnect()方法來退訂信號。該方法原型為:disconnect(receiver,sender=ANY)
其中:receiver為先前connect()函數的第一個參數receiver。sender為信號的發送者。
信號訂閱裝飾器:
Blinker 1.1版本中還可以用connect_via()裝飾器輕松訂閱信號:
from flask import template_renderd
@template_rendered.connect_via(app)
def when_template_rendered(sender,template,context,**extra):
??? print 'Template %s is rendered with %s' %(template.name,context)
核心信號:
Flask 中有以下信號:
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)
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關鍵字參數,如果這個參數存在的話。 這個參數是引發崩潰的異常的引用。
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關鍵字參數,如果這個參數存在的話。這個參數是引發崩潰的 異常的引用。
flask.appcontext_pushed
當一個應用的環境被壓入時,應用會發送這個信號。這個信號通常用于在單元測試中 臨時鉤接信息。例如可以用于改變g對象中現存的資源。
用法示例:
from?contextlib?import?contextmanagerfrom- flask?import?appcontext_pushed
- @contextmanagerdef?user_set(app,?user):def?handler(sender,?**kwargs):g.user?=?userwith?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.
appcontext_popped
當一個應用的環境被彈出時,應用會發送這個信號。這個信號通常寫成appcontext_tearing_down 信號。
New in version 0.10.
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)
轉載于:https://my.oschina.net/935572630/blog/372241
總結
以上是生活随笔為你收集整理的flask中的信号机制的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: UIDocumentInteractio
- 下一篇: C语言及程序设计初步例程-37 循环嵌套