最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Python Web框架Flask信號機(jī)制(signals)介紹

 更新時間:2015年01月01日 09:45:14   投稿:junjie  
這篇文章主要介紹了Python Web框架Flask信號機(jī)制(signals)介紹,本文介紹Flask的信號機(jī)制,講述信號的用途,并給出創(chuàng)建信號、訂閱信號、發(fā)送信號的方法,需要的朋友可以參考下

信號(signals)

Flask信號(signals, or event hooking)允許特定的發(fā)送端通知訂閱者發(fā)生了什么(既然知道發(fā)生了什么,那我們可以知道接下來該做什么了)。

Flask提供了一些信號(核心信號)且其它的擴(kuò)展提供更多的信號。信號是用于通知訂閱者,而不應(yīng)該鼓勵訂閱者修改數(shù)據(jù)。相關(guān)信號請查閱文檔。

信號依賴于Blinker庫。

鉤子(hooks)

Flask鉤子(通常出現(xiàn)在藍(lán)圖或應(yīng)用程序現(xiàn)存的方法中,比如一些內(nèi)置裝飾器,例如before_request)不需要Blinker庫并且允許你改變請求對象(request)或者響應(yīng)對象(response)。這些改變了應(yīng)用程序(或者藍(lán)圖)的行為。比如before_request()裝飾器。

信號看起來和鉤子做同樣的事情。然而在工作方式上它們存在不同。譬如核心的before_request()處理程序以特定的順序執(zhí)行,并且可以在返回響應(yīng)之前放棄請求。相比之下,所有的信號處理器是無序執(zhí)行的,并且不修改任何數(shù)據(jù)。

一般來說,鉤子用于改變行為(比如,身份驗證或錯誤處理),而信號用于記錄事件(比如記錄日志)。

創(chuàng)建信號

因為信號依賴于Blinker庫,請確保已經(jīng)安裝。

如果你要在自己的應(yīng)用中使用信號,你可以直接使用Blinker庫。最常見的使用情況是命名一個自定義的Namespace的信號。這也是大多數(shù)時候推薦的做法:


復(fù)制代碼 代碼如下:

from blinker import Namespace
my_signals = Namespace()


現(xiàn)在你可以像這樣創(chuàng)建新的信號:


復(fù)制代碼 代碼如下:

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


這里使用唯一的信號名并且簡化調(diào)試??梢杂胣ame屬性來訪問信號名。

對擴(kuò)展開發(fā)者:

如果你正在編寫一個Flask擴(kuò)展,你想優(yōu)雅地減少缺少Blinker安裝的影響,你可以這樣做使用flask.signals.Namespace類。

訂閱信號

你可以使用信號的connect()方法來訂閱信號。第一個參數(shù)是信號發(fā)出時要調(diào)用的函數(shù),第二個參數(shù)是可選的,用于確定信號的發(fā)送者。一個信號可以擁有多個訂閱者。你可以用disconnect()方法來退訂信號。

對于所有的核心Flask信號,發(fā)送者都是發(fā)出信號的應(yīng)用。當(dāng)你訂閱一個信號,請確保也提供一個發(fā)送者,除非你確實想監(jiān)聽全部應(yīng)用的信號。這在你開發(fā)一個擴(kuò)展的時候尤其正確。

比如這里有一個用于在單元測試中找出哪個模板被渲染和傳入模板的變量的助手上下文管理器:


復(fù)制代碼 代碼如下:

from flask import template_rendered
from contextlib import contextmanager

@contextmanager
def captured_templates(app):
    recorded = []
    def record(sender, template, context, **extra):
        recorded.append((template, context))
    template_rendered.connect(record, app)
    try:
        yield recorded
    finally:
        template_rendered.disconnect(record, app)


現(xiàn)在可以輕松地與測試客戶端配對:


復(fù)制代碼 代碼如下:

with captured_templates(app) as templates:
    rv = app.test_client().get('/')
    assert rv.status_code == 200
    assert len(templates) == 1
    template, context = templates[0]
    assert template.name == 'index.html'
    assert len(context['items']) == 10


確保訂閱使用了一個額外的 **extra 參數(shù),這樣當(dāng) Flask 對信號引入新參數(shù)時你的調(diào)用不會失敗。

代碼中,從 with 塊的應(yīng)用 app 中流出的渲染的所有模板現(xiàn)在會被記錄到templates 變量。無論何時模板被渲染,模板對象的上下文中添加上它。

此外,也有一個方便的助手方法(connected_to()) ,它允許你臨時地用它自己的上下文管理器把函數(shù)訂閱到信號。因為上下文管理器的返回值不能按那種方法給定,則需要把列表作為參數(shù)傳入:


復(fù)制代碼 代碼如下:

from flask import template_rendered

def captured_templates(app, recorded, **extra):
    def record(sender, template, context):
        recorded.append((template, context))
    return template_rendered.connected_to(record, app)


上面的例子看起來像這樣:


復(fù)制代碼 代碼如下:

templates = []
with captured_templates(app, templates, **extra):
    ...
    template, context = templates[0]

發(fā)送信號

如果你想要發(fā)送信號,你可以通過調(diào)用 send() 方法來達(dá)到目的。它接受一個發(fā)件者作為第一個參數(shù)和一些可選的被轉(zhuǎn)發(fā)到信號用戶的關(guān)鍵字參數(shù):


復(fù)制代碼 代碼如下:

class Model(object):
    ...

    def save(self):
        model_saved.send(self)


永遠(yuǎn)嘗試選擇一個合適的發(fā)送者。如果你有一個發(fā)出信號的類,把 self 作為發(fā)送者。如果你從一個隨機(jī)的函數(shù)發(fā)出信號,把current_app._get_current_object()作為發(fā)送者。

基于信號訂閱的裝飾器

在Blinker 1.1中通過使用新的connect_via()裝飾器你也能夠輕易地訂閱信號:

復(fù)制代碼 代碼如下:

from flask import template_rendered

@template_rendered.connect_via(app)
def when_template_rendered(sender, template, context, **extra):
    print 'Template %s is rendered with %s' % (template.name, context)

舉例

模板渲染

template_rendered信號是Flask核心信號。

當(dāng)一個模版成功地渲染,這個信號會被發(fā)送。這個信號與模板實例 template 和上下文的詞典(名為 context )一起調(diào)用。

信號發(fā)送:

復(fù)制代碼 代碼如下:

def _render(template, context, app):
    """Renders the template and fires the signal"""
    rv = template.render(context)
    template_rendered.send(app, template=template, context=context)
    return rv

訂閱示例:
復(fù)制代碼 代碼如下:

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)


帳號追蹤

user_logged_in是Flask-User中定義的信號,當(dāng)用戶成功登入之后,這個信號會被發(fā)送。

發(fā)送信號:

復(fù)制代碼 代碼如下:

# Send user_logged_in signal
user_logged_in.send(current_app._get_current_object(), user=user)

下面這個例子追蹤登錄次數(shù)和登錄IP:
復(fù)制代碼 代碼如下:

# This code has not been tested

from flask import request
from flask_user.signals import user_logged_in

@user_logged_in.connect_via(app)
def _track_logins(sender, user, **extra):
    user.login_count += 1
    user.last_login_ip = request.remote_addr
    db.session.add(user)
    db.session.commit()

小結(jié)

信號可以讓你在一瞬間安全地訂閱它們。例如,這些臨時的訂閱對測試很有幫助。使用信號時,不要讓信號訂閱者(接收者)發(fā)生異常,因為異常會造成程序中斷。

相關(guān)文章

  • Django 設(shè)置admin后臺表和App(應(yīng)用)為中文名的操作方法

    Django 設(shè)置admin后臺表和App(應(yīng)用)為中文名的操作方法

    這篇文章主要介紹了Django 設(shè)置admin后臺表和App(應(yīng)用)為中文名的操作方法,本文通過實例代碼給大家介紹的非常詳細(xì),對大家的學(xué)習(xí)或工作具有一定的參考借鑒價值,需要的朋友可以參考下
    2020-05-05
  • 淺談python中的錯誤與異常

    淺談python中的錯誤與異常

    寫Python代碼的小伙伴不可避免地會遇到代碼執(zhí)行錯誤和異常,這次就來詳細(xì)的總結(jié)一下python中的錯誤和異常
    2021-06-06
  • python中matplotlib實現(xiàn)最小二乘法擬合的過程詳解

    python中matplotlib實現(xiàn)最小二乘法擬合的過程詳解

    這篇文章主要給大家介紹了關(guān)于python中matplotlib實現(xiàn)最小二乘法擬合的相關(guān)資料,文中通過示例代碼詳細(xì)介紹了關(guān)于最小二乘法擬合直線和最小二乘法擬合曲線的實現(xiàn)過程,需要的朋友可以參考借鑒,下面來一起看看吧。
    2017-07-07
  • python安裝whl文件的實戰(zhàn)步驟

    python安裝whl文件的實戰(zhàn)步驟

    whl格式本質(zhì)上是一個壓縮包,里面包含了py文件,以及經(jīng)過編譯的pyd文件,下面這篇文章主要給大家介紹了關(guān)于python安裝whl文件的相關(guān)資料,文中通過圖文介紹的非常詳細(xì),需要的朋友可以參考下
    2022-07-07
  • celery異步定時任務(wù)訂單定時回滾

    celery異步定時任務(wù)訂單定時回滾

    這篇文章主要為大家介紹了celery異步定時任務(wù)訂單定時回滾的實現(xiàn)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步早日升職加薪
    2022-04-04
  • 使用python爬蟲實現(xiàn)網(wǎng)絡(luò)股票信息爬取的demo

    使用python爬蟲實現(xiàn)網(wǎng)絡(luò)股票信息爬取的demo

    下面小編就為大家分享一篇使用python爬蟲實現(xiàn)網(wǎng)絡(luò)股票信息爬取的demo,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2018-01-01
  • 基于hashlib模塊--加密(詳解)

    基于hashlib模塊--加密(詳解)

    下面小編就為大家?guī)硪黄趆ashlib模塊--加密(詳解)。小編覺得挺不錯的。現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-06-06
  • Python裝飾器入門學(xué)習(xí)教程(九步學(xué)習(xí))

    Python裝飾器入門學(xué)習(xí)教程(九步學(xué)習(xí))

    裝飾器(decorator)是一種高級Python語法。裝飾器可以對一個函數(shù)、方法或者類進(jìn)行加工。本文給大家介紹Python裝飾器入門學(xué)習(xí)教程(九步學(xué)習(xí)),對python裝飾器相關(guān)知識感興趣的朋友一起學(xué)習(xí)吧
    2016-01-01
  • python 如何去除字符串頭尾的多余符號

    python 如何去除字符串頭尾的多余符號

    這篇文章主要介紹了python 如何去除字符串頭尾的多余符號,在python開發(fā)中經(jīng)常會遇到這樣的需求,今天小編通過實例代碼給大家講解,需要的朋友可以參考下
    2019-11-11
  • python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解

    python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解

    這篇文章主要介紹了python爬蟲爬取筆趣網(wǎng)小說網(wǎng)站過程圖解,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下
    2019-11-11

最新評論

上栗县| 犍为县| 东丰县| 岳阳市| 南开区| 宜宾市| 玉林市| 龙泉市| 安新县| 阜宁县| 南平市| 珠海市| 达孜县| 临武县| 新余市| 福贡县| 常宁市| 新乡市| 固始县| 城市| 乐山市| 南投县| 娱乐| 调兵山市| 阿鲁科尔沁旗| 含山县| 陇南市| 冀州市| 屯昌县| 旬邑县| 合水县| 江安县| 靖宇县| 迁安市| 彭州市| 水城县| 九江县| 汝城县| 保定市| 方山县| 开封县|