信號(Django信號、Flask信號、Scrapy信號)

簡介

Django、Flask、scrapy都包含了一個「信號分配器」,使得當一些動做在框架的其餘地方發生的時候,解耦的應用能夠獲得提醒。html

通俗來說,就是一些動做發生的時候,信號容許特定的發送者去提醒一些接受者,這是特別有用的設計由於有些代碼對某些事件是特別感興趣的,好比刪除動做。python

下面,分別介紹一下三種信號的使用示例。sql

Django信號

不少數狀況下,咱們須要在操做數據庫以前或者以後作某些操做,好比說寫個日誌之類的,咱們固然能夠找到每個sql語句,在其先後加一段代碼,數據庫

可是,這不但浪費時間,還爲之後的維護增長了難度,這個時候,就體現出信號的做用了。下面的代碼是Django中對數據庫增長一條數據的操做:django

# models.py

from django.db import models

class User(models.Model):
    title = models.CharField(max_length=32)


# views.py

from django.shortcuts import render,HttpResponse
from app01 import models

def func1(request):
    models.User.objects.create(title='付勇')
    return HttpResponse('建立成功')

def func2(request):
    models.User.objects.create(title='小男孩')
    return HttpResponse('建立成功')

def func3(request):
    models.User.objects.create(title='小少年')
    return HttpResponse('建立成功')

def func4(request):
    models.User.objects.create(title='小青年')
    return HttpResponse('建立成功')

 這個時候,若是咱們想要在每增長一條數據以後在控制檯打印一句話(固然能夠換成其餘操做)的話,就能夠在項目下的__init__.py中進行信號操做,代碼以下:flask

from django.db.models import signals

def before_save1(*args,**kwargs):
    print('before_save1--->',args,kwargs)

def before_save2(*args,**kwargs):
    print('before_save2--->',args,kwargs)

def after_save1(*args,**kwargs):
    print('after_save2---->',args,kwargs)

# 在增長數據以前執行before_save1函數
signals.pre_save.connect(before_save1)

# 在增長數據以前執行before_save2函數
signals.pre_save.connect(before_save2)

# 在增長數據以後執行after_save1函數
signals.post_save.connect(after_save1)

Django中的內置信號:app

Model signals
    pre_init                    # django的modal執行其構造方法前,自動觸發
    post_init                   # django的modal執行其構造方法後,自動觸發
    pre_save                    # django的modal對象保存前,自動觸發
    post_save                   # django的modal對象保存後,自動觸發
    pre_delete                  # django的modal對象刪除前,自動觸發
    post_delete                 # django的modal對象刪除後,自動觸發
    m2m_changed                 # django的modal中使用m2m字段操做第三張表(add,remove,clear)先後,自動觸發
    class_prepared              # 程序啓動時,檢測已註冊的app中modal類,對於每個類,自動觸發
Management signals
    pre_migrate                 # 執行migrate命令前,自動觸發
    post_migrate                # 執行migrate命令後,自動觸發
Request/response signals
    request_started             # 請求到來前,自動觸發
    request_finished            # 請求結束後,自動觸發
    got_request_exception       # 請求異常後,自動觸發
Test signals
    setting_changed             # 使用test測試修改配置文件時,自動觸發
    template_rendered           # 使用test測試渲染模板時,自動觸發
Database Wrappers
    connection_created          # 建立數據庫鏈接時,自動觸發

Flask信號

項目功能複雜,代碼量越大,就越須要作業務解耦。不然在其之上作開發和維護是很痛苦的,尤爲是對於團隊的新人。框架

Flask從0.6開始,經過Blinker提供了信號支持。信號就是在框架核心功能或者一些Flask擴展發生工做時所發送的通知,用於幫助你解耦應用。scrapy

若是須要在Flask中使用信號,須要先安裝blinker組件:ide

pip install blinker

使用信號代碼以下:

from flask import Flask,render_template
from flask import signals

app = Flask(__name__)

def x1(arg):
    print('x1')
def x2(arg):
    print('x2')
    
# 在發起請求以前執行x1函數
signals.request_started.connect(x1)
# 在發起請求以前執行x2函數
signals.request_started.connect(x2)


@app.route('/index')
def func():
    print('視圖函數')
    return "ok"


if __name__ == '__main__':
    app.run()

Flask中內置的信號:

1. template_rendered:模版渲染完成後的信號。

2. before_render_template:模版渲染以前的信號。

3. request_started:模版開始渲染。

4. request_finished:模版渲染完成。

5. request_tearing_down:request對象被銷燬的信號。

6. got_request_exception:視圖函數發生異常的信號。通常能夠監聽這個信號,來記錄網站異常信息。

7. appcontext_tearing_down:app上下文被銷燬的信號。

8. appcontext_pushed:app上下文被推入到棧上的信號。

9. appcontext_popped:app上下文被推出棧中的信號

10. message_flashed:調用了Flask的`flashed`方法的信號。

Scrapy信號

Scrapy使用信號來通知事情發生。您能夠在您的Scrapy項目中捕捉一些信號(使用 extension)來完成額外的工做或添加額外的功能,擴展Scrapy。

雖然信號提供了一些參數,不過處理函數不用接收全部的參數 - 信號分發機制(singal dispatching mechanism)僅僅提供處理器(handler)接受的參數。

使用的時候新建一個py文件,如ext.py,代碼以下:

from scrapy import signals

class MyExtend(object):
    def __init__(self):
        pass

    @classmethod
    def from_crawler(cls, crawler):
        self = cls()
        # 爬蟲啓動的時候執行x1方法
        crawler.signals.connect(self.x1, signal=signals.spider_opened)
        # 爬蟲啓動的時候執行x2方法
        crawler.signals.connect(self.x2, signal=signals.spider_closed)

        return self

    def x1(self, spider):
        print('open')

    def x2(self, spider):
        print('close')    

Scrapy內置的信號:

engine_started

scrapy.signals.engine_started()

當scrapy引擎啓動爬取時發送該信號

該信號支持返回deferreds

當信號可能會在信號spider_opened以後被髮送,取決於spider的啓動方式

engine_stopped

scrapy.signals.engine_stopped()

當scrapy引擎中止時發送該信號例如爬取結束

該信號支持返回deferreds

item_scraped

scrapy.signals.item_scrapped(item,response,spider)

當item被爬取,並經過Item Pipeline後沒有被dropped時發送,該信號支持返回deferreds

參數:爬取到的item對象

      爬取item的spider對象

   提取item的response對象

item_dropped

scrapy.signals.item_dropped(item,exception,spider)

當item經過Item Pipeline,有些pipeline拋出DropItem異常,丟棄item時發送,該信號支持返回deferreds

參數:Item Pipeline丟棄的item

      爬取item的spider對象

   致使item被丟棄的異常,必須是DropItem的子類

spider_closed

scrapy.signals.spider_closed(spider,reason)

當某個spider被關閉時發送,該信號能夠用來釋放每一個spider在spider_opened後佔用的資源

該信號支持返回deferreds

參數:被關閉的spider對象

      描述spider被關閉的緣由的字符串。若是spider是因爲完成爬取而被關閉,則其爲‘finished'。若是spider是被引擎的close_spider方法所關閉,則其爲調用該方法時的reason參數(默認爲'cancelled')。若是引擎被關閉好比輸入Ctrl + C ,則爲'shutdown'

spider_opened

scrapy.signals.spider_opened(spider)

當spider開始爬取時發送該信號。該信號支持返回deferreds

參數:開啓的spider對象

spider_idle

scrapy.signals.spider_idle(spider)

當spider進入空閒狀態時發送該信號。

空閒意味着:requests正在等待被下載

      requests被調度

      items正在item pipeline中處理

當該信號的全部處理器handler被調用後,若是spider仍然保持空閒狀態,引擎將會關閉該spider。當spider被關閉後,spider_closed信號將被髮送

能夠在spider_idle處理器中調度某些請求來避免spider被關閉。該信號不支持返回deferreds

參數:空閒的spider對象

spider_error

scrapy.signals.spider_error(failure,response,spider)

當spider的回調函數產生錯誤時發送該信號

參數:以Twisted Failure對象拋出的異常

   當異常被拋出時被處理的response對象

      拋出異常的spider對象

request_scheduled

scrapy.signals.request_scheduled(request,spider)

當引擎調度一個request對象用於下載時,該信號被髮送,該信號不支持返回deferreds

參數:到達調度器的request對象

   產生該request的spider對象

response_received

scrapy.signals.response_received(response,request,spider)

當引擎從downloader獲取一個新的response時發送該信號,該信號不支持返回deferreds

參數:接受的response對象

   生成response的request對象

   response對應的spider對象

response_downloaded

scrapy.siganls.response_downloaded(response,request,spider)

當一個HttpResponse被下載時,由downloader發送該信號,該信號不支持返回deferreds

參數:下載的response對象

       生成response的request對象

     response對應的spider對象
相關文章
相關標籤/搜索