日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

python杂志订阅系统详细设计_从发布-订阅模式谈谈 Flask 的 Signals

發(fā)布時間:2024/5/8 python 54 豆豆
生活随笔 收集整理的這篇文章主要介紹了 python杂志订阅系统详细设计_从发布-订阅模式谈谈 Flask 的 Signals 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

發(fā)布-訂閱模式

發(fā)布-訂閱模式,顧名思義,就像大家訂報紙一樣,出版社發(fā)布不同類型的報紙雜志不同的讀者根據(jù)不同的需求預(yù)定符合自己口味的的報紙雜志,付費之后由郵局安排人員統(tǒng)一派送.

上面一段話,提到了發(fā)布-訂閱模式三個比較重要的點:發(fā)布者:報社

訂閱者:讀者

調(diào)度中心:郵局

不難看出上述過程中出版社和讀者完全沒有任何接觸,在他們沒有感知到對方的情況下通過郵局完成了整個流程,郵局就是傳說中的中介(Broker)

那么使用發(fā)布-訂閱模式的有什么優(yōu)點呢?這里就簡單的說兩點:松耦合,可拓展性,稍后通過例子進行講解. 關(guān)于更深入的理解可以參考:Publish/Subscribe?docs.microsoft.comPublish/Subscribe-Wikipedia?en.wikipedia.org

對這個模式有所了解之后,讓我們再回到 Flask 的 Signals

Flask - Signals

說明

有了前面這個鋪墊,不難意識到 Flask 的 Singals 其實就是我們上面說的發(fā)布-訂閱模式的實現(xiàn).官方文檔對 Signals 的介紹過于簡單,容易讓初學(xué)者直接忽略過去,但是實際上這知識點十分重要,尤其在開發(fā)比較復(fù)雜的系統(tǒng)中,正確地使用 Singals 能夠幫助我們實現(xiàn)系統(tǒng)的松耦合.

這種松耦合是通過某些行為被觸發(fā)時,自動發(fā)送定義好的一種信號,與這個信號綁定的一些業(yè)務(wù)邏輯或行為,接收到這個信號后,會自動執(zhí)行各自相應(yīng)的業(yè)務(wù)邏輯。這些行為的產(chǎn)生者就是我們在發(fā)布訂閱模式中發(fā)布者,通過調(diào)度中心,消息被轉(zhuǎn)發(fā)到相應(yīng)的訂閱者,然后每個訂閱者執(zhí)行自己的邏輯,互不干擾.

就像我們在發(fā)布-訂閱模式看到的那樣,我們可以隨時添加訂閱者. 同樣地,與該信號綁定的業(yè)務(wù)邏輯,可以是我們事先預(yù)定義好的,也可以是在后續(xù)開發(fā)中隨需求變動新增上去的. 在基于 Signals 的機制下,系統(tǒng)會更加穩(wěn)定和可擴展,也使得系統(tǒng)的業(yè)務(wù)邏輯更加清晰.

既然有這么多好處,那么該怎么使用呢?別著急,看一下幾個例子.

例子

Signal 的創(chuàng)建

兩行代碼就可以創(chuàng)建 Singals

from blinker import signal

test= signal('test')

不過 Flask 文檔中有另外一種寫法

from blinker import Namespace

my_signals = Namespace()

model_saved = my_signals.signal('model-saved')

兩者本質(zhì)上是沒有任何區(qū)別的,原因我們可以看一下 blinker 的源碼

# https://github.com/jek/blinker/blob/master/blinker/base.py

signal = Namespace().signal

很顯然從源碼看兩者基本上可以等價起來,前者只是幫助我們簡化了一個步驟

Signal 的發(fā)送

signal 創(chuàng)建好了之后,接下來就是使用了,使用很簡單通過調(diào)用 send() 函數(shù).需要注意的是,官方文檔給了一個建議:Try to always pick a good sender. If you have a class that is emitting a signal, pass self as sender. If you are emitting a signal from a random function, you can pass current_app._get_current_object() as sender.

也就說明我們在實際使用過程中,最好將 send() 函數(shù)的第一個參數(shù)為 signal 的發(fā)送者在類中發(fā)送者(sender) 為 self

class Model(object):

def save(self):

model_saved.send(self)在函數(shù)中發(fā)送者(sender) 為 current_app._get_current_object()

def save():

model_saved.send(current_app._get_current_object())

發(fā)送完消息,消息需要有人看,自然需要訂閱者了.

Signal 的訂閱

訂閱指定的 signal 可以通過使用 connect() 函數(shù),當(dāng)通過 send() 發(fā)送 signal 時,會自動觸發(fā)這些訂閱者,然后執(zhí)行相應(yīng)邏輯,從而完成相應(yīng)的功能. 使用起來很簡單,只需要給指定的函數(shù)加上一個 connect_via 或者 connect 的裝飾器就可以了

# connect_viafrom flask import Flask,current_app

app = Flask(__name__)

from blinker import Namespace

my_signals = Namespace()

test = my_signals.signal('test')

@test.connect_via(app)def subscriber(sender,**kwargs):

print(f'Got a signal sent by {sender},{kwargs}')

@app.route('/')def hello_world():

test.send(current_app._get_current_object(),data=3)

test.send('test')

return 'Hello, World!'

if __name__ == '__main__':

app.run()

讓我們執(zhí)行一下然后看一下結(jié)果:

* Serving Flask app "test" (lazy loading)

* Environment: production

WARNING: This is a development server. Do not use it in a production deployment.

Use a production WSGI server instead.

* Debug mode: on

* Restarting with stat

* Debugger is active!

* Debugger PIN: 326-510-904

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Got a signal sent by ,{'data': 3}

127.0.0.1 - - [24/Jun/2019 15:07:31] "GET / HTTP/1.1" 200 -

似乎少了依次輸出?別著急,我們修改一下這個例子,使用 connect

# connect@test.connectdef subscriber(sender,**kwargs):

print(f'Got a signal sent by {sender},{kwargs}')

再次執(zhí)行看一下結(jié)果

* Serving Flask app "test" (lazy loading)

* Environment: production

WARNING: This is a development server. Do not use it in a production deployment.

Use a production WSGI server instead.

* Debug mode: on

* Restarting with stat

* Debugger is active!

* Debugger PIN: 326-510-904

* Running on http://127.0.0.1:5000/ (Press CTRL+C to quit)

Got a signal sent by ,{'data': 3}

Got a signal sent by test,{}

127.0.0.1 - - [24/Jun/2019 15:10:43] "GET / HTTP/1.1" 200 -

connect_via 和 connect

從上面最后一次輸出,不難發(fā)現(xiàn)輸出兩次了,為什么第一次的時候只輸出了一次呢? 很顯然這就是 connect_via 和 connect 的區(qū)別,從上面的例子,我們不難看到, connect_via 多了一個參數(shù),這個參數(shù)就是 sender,使用 connect 的訂閱方式并不支持訂閱指定的發(fā)布者,如果我們需要訂閱指定的發(fā)布者需要使用 connect_via(sender)

參考發(fā)布-訂閱模式解釋?blog.csdn.netblinker?github.comSignals - Flask 0.12.4 documentation?flask.pocoo.org

總結(jié)

以上是生活随笔為你收集整理的python杂志订阅系统详细设计_从发布-订阅模式谈谈 Flask 的 Signals的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。