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

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ethan-running

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值