flask,scrapy,django信号

时间:2022-09-05 19:08:20

简介

Django、Flask、scrapy都包含了一个“信号分配器”,使得当一些动作在框架的其他地方发生的时候,解耦的应用可以得到提醒。

通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒一些接受者,这是特别有用的设计因为有些代码对某些事件是特别感兴趣的,比如删除动作。

下面,分别介绍一下三种信号的使用示例。

Django信号

很多数情况下,我们需要在操作数据库之前或者之后做某些操作,比如说写个日志之类的,我们当然可以找到每一个sql语句,在其前后加一段代码,

但是,这不但浪费时间,还为以后的维护增加了难度,这个时候,就体现出信号的作用了。下面的代码是Django中对数据库增加一条数据的操作:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# 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中进行信号操作,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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中的内置信号:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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扩展发生工作时所发送的通知,用于帮助你解耦应用。

如果需要在Flask中使用信号,需要先安装blinker组件:

1
pip install blinker

使用信号代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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,代码如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
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内置的信号:

+?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
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对象

 文章出处 https://www.cnblogs.com/fu-yong/p/9260252.html 

flask,scrapy,django信号的更多相关文章

  1. 信号(Django信号、Flask信号、Scrapy信号)

    简介 Django.Flask.scrapy都包含了一个“信号分配器”,使得当一些动作在框架的其他地方发生的时候,解耦的应用可以得到提醒. 通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒 ...

  2. Django 信号signal

    序言 Django自带一套信号机制来帮助我们在框架的不同应用位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将信号(signals)发送给一组接收者(r ...

  3. 详说Flask、Django、Pyramid三大主流 Web 框架

    前言 目前随着 Python 在大数据.云计算.人工智能方面的热度,Python Web 应该也会被更多企业了解使用. Python Web 框架千万种,没必要都去了解和学习,身边总有人说高手都用 F ...

  4. 如何理解Nginx, WSGI, Flask(Django)之间的关系

    如何理解Nginx, WSGI, Flask(Django)之间的关系 值得指出的是,WSGI 是一种协议,需要区分几个相近的名词: uwsgi 同 wsgi 一样也是一种协议,uWSGI服务器正是使 ...

  5. Django信号机制相关解释与示例

    Django 信号# django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发 ...

  6. Django 信号使用问题

    Django 信号使用问题: 在使用django内置信号修改新注册的用户密码的时候,发现内置信号没有被触发.百度&官方文档找到了答案 1.信号的函数应该放在哪里? 这段代码应该放在哪里? 严格 ...

  7. Flask 和 Django 框架的区别

    1)Flask Flask确实很“轻”,不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 Flask*.灵活,可扩展性强,第三方库的选 ...

  8. Flask与Django哪个更好更实用呢?砖家是这么认为的

        这一周我打算做一个 Flask 教程.本文先把 Flask 和 Django 做一个比对,因为我对这两个 Python Web 框架都有实际的开发经验.希望我可以帮助您选择学习哪个框架,因为学 ...

  9. Flask与Django的比较

    Flask与Django的区别 Flask Flask确实很"轻",不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 ...

随机推荐

  1. mormot json操作

    使用JSon只需要引用一个文件synCommons. procedure TForm1.Button1Click(Sender: TObject);var jo: Variant; i: Int64; ...

  2. jsp学习(2)jsp标签

    1.脚本程序 脚本程序可以包含任意量的Java语句.变量.方法或表达式,只要它们在脚本语言中是有效的. 脚本程序的语法格式:<%代码片段%>您也可以编写与其等价的XML语句,就像下面这样: ...

  3. python之命令行参数解析模块argparse

    """argparse模块使得写用户友好性命令行接口很容易,程序定义所需要的参数,argparse会从ays.argv中提取出这些参数.argparse模块也能自动的产生 ...

  4. MySQL字符集与校对

    一.什么是字符集与校对 1.字符集与校对 字符集是指一种从二进制编码到某种字符符号的映射. 校队是指一组用于某个字符集的配许规则. 2.utf8与utf8mb4 标准的UTF-8字符集编码是可以使用1 ...

  5. 深入浅出 JMS&lpar;一&rpar; - JMS 基本概念

    深入浅出 JMS(一) - JMS 基本概念 一.JMS 是个什么鬼 JMS 是 Java Message Service 的简称,即 Java 消息服务.什么是消息服务呢,我们来看一下 Oracle ...

  6. 排序算法——Shell排序

    二.Shell排序 Shell排序也叫“缩减增量排序”(disminishing increment sort),基于插入排序进行. Shell建议的序列是一种常用但不理想的增量序列:1,...,N/ ...

  7. postman优缺点

    postman优缺点分析 优点:门槛低,上手快 优点: 脚本语言是js 优点:自带各种代码模块 优点:跨平台 优点: 免费版就已经非常强大了,支持http,https协议 优点:有命令行版本,newm ...

  8. Winter-1-A A &plus; B 解题报告及测试数据

    Time Limit:1000MS Memory Limit:32768KB Description Calculate A + B. Input Each line will contain two ...

  9. Spoken English Practice&lpar; Believe it or not&comma; I don&&num;39&semi;t need to make believe its a big deal&period; &lpar;believe&comma;deal&comma; You don&&num;39&semi;t say&rpar;&rpar;

    音标复习                                                绿色:连读:红色:略读:蓝色:浊化:橙色:弱读 口语蜕变(2017/6/25) Sorry, t ...

  10. java基础&lpar;2&rpar;--进制

    进制 进制基础, 目的:理解计算机只能处理2进制的数据和指令 1)10进制计数规律 数字: 0 1 2 3 4 5 6 7 8 9 基数:10 权:  1000 100 10 1 权是基数的n次幂 2 ...