Flask入门(11):信号机制

Django一样,Flask也提供了信号机制。

从 Flask 0.6 开始, Flask 集成了信号支持。这个支持由 blinker 库提供, 并且当它不可用时会优雅地退回。

什么是信号

信号通过发送发生在核心框架的其它地方或 Flask 扩展的动作时的通知来帮助你解耦应用。简而言之,信号允许特定的发送端通知订阅者发生了什么。

主要目的是解耦应用。

Flask中的信号与中间件有一些相似之处,但是本质的工作范畴截然不同:

  1. Flask中的中间件的目的是拦截请求或定义一些全局操作,这些中间件共同特性都是具有返回值的;信号是在某个特殊情况发生后,进行额外的操作,对代码进行解耦合一般不会对其设置返回值
  2. Flask中的中间件以特定的顺序执行,并且可以在返回响应之前放弃请求。相比之下,所有的信号处理器执行的顺序没有定义,并且不修改任何数据

内置信号

以下是所有的内置信号:

信号 描述
request_started 请求到来前执行
request_finished 请求结束后执行
before_render_template 模板渲染前执行
template_rendered 模板渲染后执行
got_request_exception 请求执行出现异常时执行
request_tearing_down 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down 应用上下文执行完毕后自动执行(无论成功与否)
appcontext_pushed 应用上下文push时执行
appcontext_popped 应用上下文pop时执行
message_flashed 向闪现消息中添加数据时,自动触发

使用信号

使用信号首先安装包blinker

pip3 install blinker

然后注册信号,有两种方式:1.使用装饰器;2.使用connect方法

import flask
from flask import signals

app = flask.Flask(__name__)

# 导入信号,注册回调函数
@signals.request_started.connect
def func(*args,**kwargs):
    print("请求到来了...")
    print(args)  # (<Flask 'flask信号'>,)
    print(kwargs)  # {}

# 第二种注册方式
# signals.request_started.connect(func)

# 请求到来前先执行信号
@app.route('/index')
def index():
    return "index"

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

启动项目,访问路由,打印如下:

请求到来了...
(<Flask 'signal_demo'>,)
{
    
    }
127.0.0.1 - - [13/May/2023 14:02:42] "GET /index HTTP/1.1" 200 -

退订一个信号,可以使用 disconnect() 方法。

自定义信号

自定义信号的使用分为三步:

  1. 定义信号;
  2. 注册新号
  3. 发送信号

如果你想要在自己的应用中使用信号,你可以直接使用 blinker 库。最常见的用法是在自定义的 Namespace 中命名信号。这也是大多数时候推荐的做法:

import time

import flask
from blinker import Namespace

app = flask.Flask(__name__)

# 1.定义信号
my_signals = Namespace()
comm_signals = my_signals.signal("comm_signals")


# 2.注册回调函数
@comm_signals.connect
def func(*args, **kwargs):
    print("来信号了...")
    time.sleep(2)
    print(args)  # ('xxx',)
    print(kwargs)  # {}


@app.route('/index')
def index():
    # 3.发送信号:相当于异步调用回调函数
    comm_signals.send("xxx")
    return "index"


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

打印如下:

来信号了...
127.0.0.1 - - [13/May/2023 14:50:52] "GET /index HTTP/1.1" 200 -
('xxx',)
{
    
    }

使用send发送信号,相当于是异步调用,路由函数会立马返回,不会被信号里的执行阻塞。

多信号执行顺序

当有一个信号进行注册多个回调函数时,按照注册顺序进行执行:

import flask
from flask import signals

app = flask.Flask(__name__)

# 导入信号,注册回调函数
@signals.request_started.connect
def func1(*args,**kwargs):
    print("func1...")


@signals.request_started.connect
def func2(*args,**kwargs):
    print("func2...")


# 请求到来前先执行信号
@app.route('/index')
def index():
    return "ok!!!"

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

参考:
https://www.cnblogs.com/Yunya-Cnblogs/p/14280010.html
https://docs.jinkan.org/docs/flask/signals.html

猜你喜欢

转载自blog.csdn.net/qq_43745578/article/details/130657617
今日推荐