信號是一種通知或者說通信的方式,信號分為發送方和接收方。發送方發送一種信號,接收方收到信號的進程會跳入信號處理函數,執行完后再跳回原來的位置繼續執行。
常見的 Linux 中的信號,通過鍵盤輸入 Ctrl+C,就是發送給系統一個信號,告訴系統退出當前進程。
信號的特點就是發送端通知訂閱者發生了什么。使用信號分為 3 步:定義信號,監聽信號,發送信號。
Python 中提供了信號概念的通信模塊,就是blinker。
Blinker 是一個基于 Python 的強大的信號庫,它既支持簡單的點對點通信,也支持點對多點的組播。Flask 的信號機制就是基于它建立的。Blinker 的內核雖然小巧,但是功能卻非常強大,它支持以下特性:
支持注冊全局命名信號
支持匿名信號
支持自定義命名信號
支持與接收者之間的持久連接與短暫連接
通過弱引用實現與接收者之間的自動斷開連接
支持發送任意大小的數據
支持收集信號接收者的返回值
線程安全
安裝方法:
pipinstallblinker
fromblinkerimportsignal#定義一個信號s=signal('king')defanimal(args):print('我是小鉆風,大王回來了,我要去巡山')#信號注冊一個接收者s.connect(animal)if"__main__"==__name__:#發送信號s.send()
blinker 也支持匿名信號,就是不需要指定一個具體的信號值。創建的每一個匿名信號都是互相獨立的。
fromblinkerimportSignals=Signal()defanimal(sender):print('我是小鉆風,大王回來了,我要去巡山')s.connect(animal)if"__main__"==__name__:s.send()
組播信號是比較能體現出信號優點的特征。多個接收者注冊到信號上,發送者只需要發送一次就能傳遞信息到多個接收者。
fromblinkerimportsignals=signal('king')defanimal_one(args):print(f'我是小鉆風,今天的口號是:{args}')defanimal_two(args):print(f'我是大鉆風,今天的口號是:{args}')s.connect(animal_one)s.connect(animal_two)if"__main__"==__name__:s.send('大王叫我來巡山,抓個和尚做晚餐!')
接受方支持訂閱指定的主題,只有當指定的主題發送消息時才發送給接收方。這種方法很好的區分了不同的主題。
fromblinkerimportsignals=signal('king')defanimal(args):print(f'我是小鉆風,{args}是我大哥')s.connect(animal,sender='大象')if"__main__"==__name__:foriin['獅子','大象','大鵬']:s.send(i)
除了可以函數注冊之外還有更簡單的信號注冊方法,那就是裝飾器。
fromblinkerimportsignals=signal('king')@s.connectdefanimal_one(args):print(f'我是小鉆風,今天的口號是:{args}')@s.connectdefanimal_two(args):print(f'我是大鉆風,今天的口號是:{args}')if"__main__"==__name__:s.send('大王叫我來巡山,抓個和尚做晚餐!')
connect的注冊方法用著裝飾器時有一個弊端就是不能夠訂閱主題,所以有更高級的connect_via方法支持訂閱主題。
fromblinkerimportsignals=signal('king')@s.connect_via('大象')defanimal(args):print(f'我是小鉆風,{args}是我大哥')if"__main__"==__name__:foriin['獅子','大象','大鵬']:s.send(i)
如果對于一個發送者發送消息前要準備的耗時很長,為了避免沒有接收者導致浪費性能的情況,所以可以先檢查某一個信號是否有接收者,在確定有接收者的情況下才發送,做到精確。
fromblinkerimportsignals=signal('king')q=signal('queue')defanimal(sender):print('我是小鉆風,大王回來了,我要去巡山')s.connect(animal)if"__main__"==__name__:res=s.receiversprint(res)ifres:s.send()res=q.receiversprint(res)ifres:q.send()else:print("孩兒們都出去巡山了")
{4511880240:}我是小鉆風,大王回來了,我要去巡山{}孩兒們都出去巡山了
也可以檢查訂閱者是否由某一個信號
fromblinkerimportsignals=signal('king')q=signal('queue')defanimal(sender):print('我是小鉆風,大王回來了,我要去巡山')s.connect(animal)if"__main__"==__name__:res=s.has_receivers_for(animal)print(res)res=q.has_receivers_for(animal)print(res)
TrueFalse
Flask 集成 blinker 作為解耦應用的解決方案。在 Flask 中,信號的使用場景如:請求到來之前,請求結束之后。同時 Flask 也支持自定義信號。
fromflaskimportFlaskapp=Flask(__name__)@app.route('/',methods=['GET','POST'],endpoint='index')defindex():return'helloblinker'if__name__=='__main__':app.run()
訪問127.0.0.1:5000時,返回給瀏覽器hello blinker。
因為 Flask 集成了信號,所以在 Flask 中使用信號時從 Flask 中引入。
fromflaskimportFlaskfromflask.signalsimport_signalsapp=Flask(__name__)s=_signals.singal('msg')defQQ(args):print('youhavemsgfromQQ')s.connect(QQ)@app.route('/',methods=['GET','POST'],endpoint='index')defindex():s.send()return'helloblinker'if__name__=='__main__':app.run()
在 Flask 中除了可以自定義信號,還可以使用自帶信號。Flask 中自帶的信號有很多種,具體如下:
請求request_started=_signals.signal('request-started')#請求到來前執行request_finished=_signals.signal('request-finished')#請求結束后執行模板渲染before_render_template=_signals.signal('before-render-template')#模板渲染前執行template_rendered=_signals.signal('template-rendered')#模板渲染后執行請求執行got_request_exception=_signals.signal('got-request-exception')#請求執行出現異常時執行request_tearing_down=_signals.signal('request-tearing-down')#請求執行完畢后自動執行(無論成功與否)appcontext_tearing_down=_signals.signal('appcontext-tearing-down')#請求上下文執行完畢后自動執行(無論成功與否)請求上下文中appcontext_pushed=_signals.signal('appcontext-pushed')#請求上下文push時執行appcontext_popped=_signals.signal('appcontext-popped')#請求上下文pop時執行message_flashed=_signals.signal('message-flashed')#調用flask在其中添加數據時,自動觸發
下面以請求到來之前為例,看 Flask 中信號如何使用
fromflaskimportFlaskfromflask.signalsimport_signals,request_startedimporttimeapp=Flask(__name__)defwechat(args):print('youhavemsgfromwechat')#從flask中引入已經定好的信號,注冊一個函數request_started.connect(wechat)@app.route('/',methods=['GET','POST'],endpoint='index')defindex():return'helloblinker'if__name__=='__main__':app.run()
當請求到來時,Flask 會經過request_started 通知接受方,就是函數wechat,這時wechat函數先執行,然后才返回結果給瀏覽器。
但這種使用方法并不是很地道,因為信號并不支持異步方法,所以通常在生產環境中信號的接收者都是配置異步執行的框架,如 Python 中大名鼎鼎的異步框架 celery。
讀到這里,這篇“Python強大的信號庫blinker怎么使用”文章已經介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領會,如果想了解更多相關內容的文章,歡迎關注本站行業資訊頻道。
本文由 貴州做網站公司 整理發布,部分圖文來源于互聯網,如有侵權,請聯系我們刪除,謝謝!
c語言中正確的字符常量是用一對單引號將一個字符括起表示合法的字符常量。例如‘a’。數值包括整型、浮點型。整型可用十進制,八進制,十六進制。八進制前面要加0,后面...
2022年天津專場考試原定于3月19日舉行,受疫情影響確定延期,但目前延期后的考試時間推遲。 符合報名條件的考生,須在規定時間登錄招考資訊網(www.zha...
:喜歡聽,樂意看。指很受歡迎?!巴卣官Y料”喜聞樂見:[ xǐ wén lè jiàn ]詳細解釋1. 【解釋】:喜歡聽,樂意看。指很受歡迎。2. 【示例】:這是...
美國次貸危機(subprime crisis)也稱次級房貸危機,也譯為次債危機。它是指一場發生在美國,因次級抵押貸款機構破產、投資基金被迫關閉、股市劇烈震蕩引起的金融風暴。那么,美國次貸危機爆發的主要原因是什么?美國次貸危機如何解決的?一起來看看吧!美國次貸危機爆發的主要原因有:1.美國金融監管當局,特別是美聯儲貨幣政策的松緊變化。2.美國投資市場,以及全球經濟和投資環境一段時期內,情緒樂觀、持續...
新股定價高的原因是什么?1、過去新股發行長期形成的“新股不敗”現象,讓投資者對注冊制新股高價發行所帶來的破發風險認識不足,盡管注冊制新股發行出現了上市首日破發的現象,但投資者仍心存僥幸,認為自己中簽的新股不會破發,還是選擇踴躍打新,導致新股發行始終處于供不應求狀態,新股發行價也因此而走高。2、市值配售打新方式帶來的負面影響。取消了23倍市盈率限制后,市值配售不再是投資者的福...
郁金香泡沫指的是人類社歷史上的第一次有確鑿記錄的金融泡沫事件。郁金香泡沫的發生的原有是因為17世紀荷蘭郁金香的初次引入,由于初期培養緩慢以及貴族之間的狂熱攀比導致的郁金香供不應求,從而出現的投機活動。郁金香泡沫被稱為歷史記載中最為瘋狂的-次投機行為,也叫做郁金香效應。16世紀中期,郁金香首次被西歐從其引入,引入沒多久就引來了西歐人民對其的狂熱追捧,富人們爭相對花園中的郁金香進行攀比展示,從而導致郁...