flask,scrapy,django信号
简介
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.pyfrom django.db import modelsclass User(models.Model): title = models.CharField(max_length=32)# views.pyfrom django.shortcuts import render,HttpResponsefrom app01 import modelsdef 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 signalsdef 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_templatefrom flask import signalsapp = 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 signalsclass 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_startedscrapy.signals.engine_started()当scrapy引擎启动爬取时发送该信号该信号支持返回deferreds当信号可能会在信号spider_opened之后被发送,取决于spider的启动方式engine_stoppedscrapy.signals.engine_stopped()当scrapy引擎停止时发送该信号例如爬取结束该信号支持返回deferredsitem_scrapedscrapy.signals.item_scrapped(item,response,spider)当item被爬取,并通过Item Pipeline后没有被dropped时发送,该信号支持返回deferreds参数:爬取到的item对象 爬取item的spider对象 提取item的response对象item_droppedscrapy.signals.item_dropped(item,exception,spider)当item通过Item Pipeline,有些pipeline抛出DropItem异常,丢弃item时发送,该信号支持返回deferreds参数:Item Pipeline丢弃的item 爬取item的spider对象 导致item被丢弃的异常,必须是DropItem的子类spider_closedscrapy.signals.spider_closed(spider,reason)当某个spider被关闭时发送,该信号可以用来释放每个spider在spider_opened后占用的资源该信号支持返回deferreds参数:被关闭的spider对象 描述spider被关闭的原因的字符串。如果spider是由于完成爬取而被关闭,则其为‘finished'。如果spider是被引擎的close_spider方法所关闭,则其为调用该方法时的reason参数(默认为'cancelled')。如果引擎被关闭比如输入Ctrl + C ,则为'shutdown'spider_openedscrapy.signals.spider_opened(spider)当spider开始爬取时发送该信号。该信号支持返回deferreds参数:开启的spider对象spider_idlescrapy.signals.spider_idle(spider)当spider进入空闲状态时发送该信号。空闲意味着:requests正在等待被下载 requests被调度 items正在item pipeline中处理当该信号的所有处理器handler被调用后,如果spider仍然保持空闲状态,引擎将会关闭该spider。当spider被关闭后,spider_closed信号将被发送可以在spider_idle处理器中调度某些请求来避免spider被关闭。该信号不支持返回deferreds参数:空闲的spider对象spider_errorscrapy.signals.spider_error(failure,response,spider)当spider的回调函数产生错误时发送该信号参数:以Twisted Failure对象抛出的异常 当异常被抛出时被处理的response对象 抛出异常的spider对象request_scheduledscrapy.signals.request_scheduled(request,spider)当引擎调度一个request对象用于下载时,该信号被发送,该信号不支持返回deferreds参数:到达调度器的request对象 产生该request的spider对象response_receivedscrapy.signals.response_received(response,request,spider)当引擎从downloader获取一个新的response时发送该信号,该信号不支持返回deferreds参数:接受的response对象 生成response的request对象 response对应的spider对象response_downloadedscrapy.siganls.response_downloaded(response,request,spider)当一个HttpResponse被下载时,由downloader发送该信号,该信号不支持返回deferreds参数:下载的response对象 生成response的request对象 response对应的spider对象 |
flask,scrapy,django信号的更多相关文章
- 信号(Django信号、Flask信号、Scrapy信号)
简介 Django.Flask.scrapy都包含了一个“信号分配器”,使得当一些动作在框架的其他地方发生的时候,解耦的应用可以得到提醒. 通俗来讲,就是一些动作发生的时候,信号允许特定的发送者去提醒 ...
- Django 信号signal
序言 Django自带一套信号机制来帮助我们在框架的不同应用位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将信号(signals)发送给一组接收者(r ...
- 详说Flask、Django、Pyramid三大主流 Web 框架
前言 目前随着 Python 在大数据.云计算.人工智能方面的热度,Python Web 应该也会被更多企业了解使用. Python Web 框架千万种,没必要都去了解和学习,身边总有人说高手都用 F ...
- 如何理解Nginx, WSGI, Flask(Django)之间的关系
如何理解Nginx, WSGI, Flask(Django)之间的关系 值得指出的是,WSGI 是一种协议,需要区分几个相近的名词: uwsgi 同 wsgi 一样也是一种协议,uWSGI服务器正是使 ...
- Django信号机制相关解释与示例
Django 信号# django自带一套信号机制来帮助我们在框架的不同位置之间传递信息.也就是说,当某一事件发生时,信号系统可以允许一个或多个发送者(senders)将通知或信号(signals)发 ...
- Django 信号使用问题
Django 信号使用问题: 在使用django内置信号修改新注册的用户密码的时候,发现内置信号没有被触发.百度&官方文档找到了答案 1.信号的函数应该放在哪里? 这段代码应该放在哪里? 严格 ...
- Flask 和 Django 框架的区别
1)Flask Flask确实很“轻”,不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 Flask自由.灵活,可扩展性强,第三方库的选 ...
- Flask与Django哪个更好更实用呢?砖家是这么认为的
这一周我打算做一个 Flask 教程.本文先把 Flask 和 Django 做一个比对,因为我对这两个 Python Web 框架都有实际的开发经验.希望我可以帮助您选择学习哪个框架,因为学 ...
- Flask与Django的比较
Flask与Django的区别 Flask Flask确实很"轻",不愧是Micro Framework,从Django转向Flask的开发者一定会如此感慨,除非二者均为深入使用过 ...
随机推荐
- 项目Beta冲刺(团队)-凡事预则立
所属课程 软件工程1916|W(福州大学) 作业要求 项目Beta冲刺(团队)-凡事预则立 团队名称 基于云的胜利冲锋队 作业目标 为 Beta 冲刺规划安排 1.讨论组长是否重选的议题和结论 由于我 ...
- Python开发笔记:网络数据抓取
网络数据获取(爬取)分为两部分: 1.抓取(抓取网页) · urlib内建模块,特别是urlib.request · Requests第三方库(中小型网络爬虫的开发) · Scrapy框架(大型网络爬 ...
- pycharm激活2018(终极解决办法)
1.将“0.0.0.0 account.jetbrains.com”中的内容添加到hosts文件中,hosts路径为:C:\Windows\System32\drivers\etc 2.打开http: ...
- Tips on Probability Theory
1.独立与不相关 随机变量X和Y相互独立,有:E(XY) = E(X)E(Y). 独立一定不相关,不相关不一定独立(高斯过程里二者等价) .对于均值为零的高斯随机变量,“独立”和“不相关”等价的. 独 ...
- windows客户端
- 洛谷 题解 P2721 【摄像头】
这是我见过最水的蓝题 这不就是拓扑排序板子题吗 题目大意:松鼠砸烂摄像头不被抓住 摄像头一个可以监视到另一个可以看做有向边,用邻接链表储存就好了,我也不知道邻接矩阵到底能不能过保险起见还是用邻接链表. ...
- CTS&&APIO2019爆零记
如果你只好奇测试相关请跳至day 2 day 3 day 6 scoi 2019 之后 由于实力问题,省选的时候排名在三十多,显然是没有进队.不过可能是受过的打击比较多,所以还没有特别颓废,甚至连 ...
- linux命令之------Linux文件系统具体目录
Linux文件系统具体目录 (1)/ Linux文件系统的入口,也是处于最高一级的目录 (2)/bin 系统所需要的那些命令处于此目录,比如Is,cp,mkdir等命令:功能和/usr/bin类似 ...
- 最近在弄ionic3的时候遇到的一些问题(遇到就更新)
问题一(install提示errno -4048 和管理员权限) npm install npm ERR! code EPERM npm ERR! errno - npm ERR! syscall u ...
- Centos 7 更换为 阿里云 yum 源
地址: https://opsx.alibaba.com/ 操作步骤: 1.备份 mv /etc/yum.repos.d/CentOS-Base.repo /etc/yum.repos.d/CentO ...