Flask中信号机制用法

1、信号机制

1.1 信号机制介绍

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

1.2 第三方库安装

        flask中的信号使用的是一个第三方插件,叫做blinker。通过pip list看一下,如果没有安装,通过以下命令即可安装blinker。

pip install blinker

Flask中信号机制用法_第1张图片

1.3 自定义信号步骤

自定义信号可分为3步来完成。

第一是创建一个信号,第二是监听一个信号,第三是发送一个信号。

以下将对这三步进行讲解:

创建信号:定义信号需要使用到blinker这个包的Namespace类来创建一个命名空间。比如定义一个在访问了某个视图函数的时候的信号。

# Namespace的作用:为了防止多人开发的时候,信号名字冲突的问题
from blinker import Namespace
mysignal = Namespace()
signal1 = mysignal.signal('信号名称')

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

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

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

signal1.send(uname='momo')

示例代码:

from flask import Flask
from blinker import Namespace

app = Flask(__name__)

# 信号机制 3步走
# 1.定义信号
signal_space = Namespace()
signal_name = signal_space.signal('访问首页')


# 2.监听信号
def main_func(sender):
    print(sender)
    print('start main_func')


signal_name.connect(main_func)


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


@app.route('/')
def index():
    print('执行index函数!')
    # 3.发送一个信号
    signal_name.send()
    return "hello world!"


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

运行结果:

Flask中信号机制用法_第2张图片

Flask中信号机制用法_第3张图片

2、信号使用-存储用户登录日志

描述:

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

编写一个signals.py文件创建登录信号:

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


name_space = Namespace()

# 创建登录信息
login_signal = name_space.signal('login')


def login_log(sender):
    now = datetime.now()
    ip = request.remote_addr
    log_data = f'{g.name}*{now}*{ip}'
    # with open('./data/login_log.txt', 'a', encoding='utf-8') as f:
    #     f.write(log_data + '\n')
    #     f.close()
    print(log_data)


# 监听信号
login_signal.connect(login_log)

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

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

app = Flask(__name__)


@app.route('/login/')
def login():
    name = request.args.get('name')
    if name:
        g.name = name
        # 发送信号
        login_signal.send()
        return '登录成功'
    else:
        return '请输入用户名'


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

运行结果:

Flask中信号机制用法_第4张图片

Flask中信号机制用法_第5张图片

3、Flask内置信号

Flask内置了10个常用的信号:

  • template_rendered:模版渲染完成后的信号。
  • before_render_template:模版渲染之前的信号。
  • request_started:请求开始之前,在到达视图函数之前发送信号。
  • request_finished:请求结束时,在响应发送给客户端之前发送信号。
  • request_tearing_down:请求对象被销毁时发送的信号,即使在请求过程中发生异常也会发送信号。
  • got_request_exception:在请求过程中抛出异常时发送信号,异常本身会通过exception传递到订阅(监听)的函数中。一般可以监听这个信号,来记录网站异常信息。
  • appcontext_tearing_down:应用上下文被销毁时发送的信号。
  • appcontext_pushed:应用上下文被推入到栈上时发送的信号。
  • appcontext_popped:应用上下文被推出栈时发送的信号。
  • message_flashed:调用了Flask的 flash 方法时发送的信号。

3.1 template_rendered的使用

示例代码:

from flask import Flask, render_template, template_rendered

app = Flask(__name__)


@app.route('/')
def index():
    return render_template('index.html')


def render_func(sender, template, context):
    print(sender)
    print(template)
    print(context)


template_rendered.connect(render_func)

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

运行结果:

Flask中信号机制用法_第6张图片

3.2 got_request_exception的使用

示例代码:

from flask import Flask, render_template, got_request_exception

app = Flask(__name__)


@app.route('/')
def index():
    1 / 0
    return render_template('index.html')


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


# def request_exception_log2(sender, exception):
#     print(sender)
#     print(exception)


got_request_exception.connect(request_exception_log)

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

运行结果:

Flask中信号机制用法_第7张图片

你可能感兴趣的:(Flask框架,python,flask,信号机制)