信號(signals)
Flask信號(signals, or event hooking)允許特定的發送端通知訂閱者發生了什么(既然知道發生了什么,那我們可以知道接下來該做什么了)。
Flask提供了一些信號(核心信號)且其它的擴展提供更多的信號。信號是用于通知訂閱者,而不應該鼓勵訂閱者修改數據。相關信號請查閱文檔。
信號依賴于Blinker庫。
鉤子(hooks)
Flask鉤子(通常出現在藍圖或應用程序現存的方法中,比如一些內置裝飾器,例如before_request)不需要Blinker庫并且允許你改變請求對象(request)或者響應對象(response)。這些改變了應用程序(或者藍圖)的行為。比如before_request()裝飾器。
信號看起來和鉤子做同樣的事情。然而在工作方式上它們存在不同。譬如核心的before_request()處理程序以特定的順序執行,并且可以在返回響應之前放棄請求。相比之下,所有的信號處理器是無序執行的,并且不修改任何數據。
一般來說,鉤子用于改變行為(比如,身份驗證或錯誤處理),而信號用于記錄事件(比如記錄日志)。
創建信號
因為信號依賴于Blinker庫,請確保已經安裝。
如果你要在自己的應用中使用信號,你可以直接使用Blinker庫。最常見的使用情況是命名一個自定義的Namespace的信號。這也是大多數時候推薦的做法:
代碼如下:
from blinker import Namespace
my_signals = Namespace()
現在你可以像這樣創建新的信號:
代碼如下:
model_saved = my_signals.signal('model-saved')
這里使用唯一的信號名并且簡化調試??梢杂胣ame屬性來訪問信號名。
對擴展開發者:
如果你正在編寫一個Flask擴展,你想優雅地減少缺少Blinker安裝的影響,你可以這樣做使用flask.signals.Namespace類。
訂閱信號
你可以使用信號的connect()方法來訂閱信號。第一個參數是信號發出時要調用的函數,第二個參數是可選的,用于確定信號的發送者。一個信號可以擁有多個訂閱者。你可以用disconnect()方法來退訂信號。
對于所有的核心Flask信號,發送者都是發出信號的應用。當你訂閱一個信號,請確保也提供一個發送者,除非你確實想監聽全部應用的信號。這在你開發一個擴展的時候尤其正確。
比如這里有一個用于在單元測試中找出哪個模板被渲染和傳入模板的變量的助手上下文管理器:
代碼如下:
from flask import template_rendered
from contextlib import contextmanager
@contextmanager
def captured_templates(app):
recorded = []
def record(sender, template, context, **extra):
新聞熱點
疑難解答