Flask之信号


信号机制

  • 类似于两方属于敌对关系时,某人在敌对方阵营进行交谈,一旦遇到特殊情况,某人便会发送信号,他的同伙接收(监听)到他发的信号后,同伙便会做出一系列的应对策略(杀进去|撤退)。

  • flask中的信号使用的是一个第三方插件,叫blinker

  • 安装blinkerpip install blinker


自定义信号步骤

1. 创建信号:

  • 定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间。
  • Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题
  • 比如定义一个在访问了某个视图函数的时候的信号。

from blinker import Namespace 

mysignal = Namespace() 
signal1 = mysignal.signal('信号名称')

2. 监听信号:

  • 监听信号使用signal1对象的connect方法,在这个方法中需要传递一个函数,用来监听到这个信号后做该做的事情。

def func1(sender,uname): 
	print(sender) 
	print(uname) 
	
signal1.connect(func1)
	

3. 发送信号:

  • 发送信号使用signal1对象的send方法,这个方法可以传递一些其他参数过去。

signal1.send(uname='wukong')


完整流程


from flask import Flask 
from blinker import Namespace 

app = Flask(__name__) 

# Namespace:命名空间 
#1.定义信号 
sSpace = Namespace() 
fire_signal = sSpace.signal('发送信号火箭') 

#2.监听信号 
def fire_play(sender): 
	print(sender) 
	print("start play") 
fire_signal.connect(fire_play) 

#3.发送一个信号 
fire_signal.send() 

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


信号使用场景

  1. 定义一个登录的信号
  2. 用户登录进来就发送一个登录信号,然后能够监听这个信号
  3. 在监听到这个信号以后,就记录当前这个用户登录的信息
  4. 用信号的方式,记录用户的登录信息即登录日志

信号具体实现

  • 创建登陆信号,以及监听

from blinker import Namespace 
from datetime import datetime 
from flask import request,g 

#创建登录信号 
namespace = Namespace() 
login_signal = namespace.signal('login') 

def login_log(sender): 
	# 用户名 登录时间 ip地址 
	now = datetime.now() 
	ip = request.remote_addr 
	log_data = "{uname}*{now}*{ip}".format(uname=g.uname, now=now, ip=ip) 
	with open('login_log.txt','a') as f: 
		f.write(log_data + "\n") 
		f.close() 
#监听信号 
login_signal.connect(login_log)

  • 使用信号存储用户登录日志

from flask import Flask,request,g 
from signals import login_signal 

app = Flask(__name__) 

@app.route('/login/') 
def login(): 
	# 通过查询字符串的形式来传递uname这个参数 
	uname = request.args.get('uname') 
	if uname: 
		g.uname = uname 

		# 发送信号 
		login_signal.send() 
		return '登录成功!' 
	else: 
		return '请输入用户名!' 

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

内置信号

  • 内置信号,已将创建信号发送信号功能完成,只需要了解其功能,做出相应的监听
  1. template_rendered:模版渲染完成后的信号。

from flask import Flask,template_rendered,render_template 

app = Flask(__name__) 

#内置信号 
#模版渲染完成后的信号。 
def template_rendered_func(sender,template,context): 
	print(sender) #发送者 
	print(template) #跳转到的模版名称 
	print(context) #跳转到模版时带过去的参数 
	
template_rendered.connect(template_rendered_func) 

@app.route('/') 
def hello_world(): 
	return render_template("index.html",data="wukong")

if __name__ == '__main__': 
	app.run(debug=True)
	
  1. before_render_template:模版渲染之前的信号。

  2. request_started:请求开始之前,在到达视图函数之前发送信号。

  3. request_finished:请求结束时,在响应发送给客户端之前发送信号。

  4. request_tearing_down:请求对象被销毁时发送的信号,即使在请求过程中发生异常也会发送信号。

  5. got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。一般可以监听这个信号,来记录网站异常信息。


from flask import Flask,request,g,template_rendered,got_request_exception,render_template 

app = Flask(__name__) 

def request_exception_log(sender,exception): 
	print(sender) 
	print(exception) 
	
got_request_exception.connect(request_exception_log)
	
@app.route('/') 
def hello_world(): 
	#制造bug 
	a = 1/0 
	return render_template("index.html",data="wukong") 

if __name__ == '__main__': 
	app.run(debug=True)
	
  1. appcontext_tearing_down:应用上下文被销毁时发送的信号。

  2. appcontext_pushed:应用上下文被推入到栈上时发送的信号。

  3. appcontext_popped:应用上下文被推出栈时发送的信号。

  4. message_flashed:调用了Flask的flash方法时发送的信号。


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值