Flask信号

news/2024/12/3 1:50:13/

文章目录

    • 信号与请求拓展的区别
    • 使用信号触发和直接调用的区别
  • 信号源码的说明
  • 内置信号说明
  • 自定义信号

信号 ---- 在满足某种情况下会触发某个函数的执行

信号与请求拓展的区别

信号可以触发一个或者多个绑定函数的执行,同时可以有返回值,而请求拓展的返回值是被严格限制的

信号的绑定程序的执行是按照绑定是的先后顺序执行的

使用信号触发和直接调用的区别

信号触发绑定函数的执行是在他自己的调用栈进行,而直接调用是在 flask 的请求上下文和全局上下文中进行的;这就意味着信号触发执行的时候是访问不到请求上下文和g对象

所以必要时,可以使用 flask 提供的请求上下文管理工具。


信号源码的说明

其实,从源码中可以看出,Namespace这个类会先尝试从blinker模块中导入’

如果导不到,就会使用下面自己写的Namespace

文件中间说明了_signals = Namespace(),所以使用这两个中的哪一个都行;

使用_signals有一个单例模式的效果,所以尽量使用这个,保证一个项目中就一个总的信号触发机制

文件最下方初始化了很多内置信号

import typing as ttry:from blinker import Namespacesignals_available = True
except ImportError:signals_available = Falseclass Namespace: # type: ignoredef signal(self, name: str, doc: t.Optional[str] = None) -> "_FakeSignal":return _FakeSignal(name, doc)class _FakeSignal:"""If blinker is unavailable, create a fake class with the sameinterface that allows sending of signals but will fail with anerror on anything else. Instead of doing anything on send, itwill just ignore the arguments and do nothing instead."""def __init__(self, name: str, doc: t.Optional[str] = None) -> None:self.name = nameself.__doc__ = docdef send(self, *args: t.Any, **kwargs: t.Any) -> t.Any:passdef _fail(self, *args: t.Any, **kwargs: t.Any) -> t.Any:raise RuntimeError("Signalling support is unavailable because the blinker"" library is not installed.") from Noneconnect = connect_via = connected_to = temporarily_connected_to = _faildisconnect = _failhas_receivers_for = receivers_for = _faildel _fail# The namespace for code signals. If you are not Flask code, do
# not put signals in here. Create your own namespace instead.
_signals = Namespace()# Core signals. For usage examples grep the source code or consult
# the API documentation in docs/api.rst as well as docs/signals.rst
template_rendered = _signals.signal("template-rendered")
before_render_template = _signals.signal("before-render-template")
request_started = _signals.signal("request-started")
request_finished = _signals.signal("request-finished")
request_tearing_down = _signals.signal("request-tearing-down")
got_request_exception = _signals.signal("got-request-exception")
appcontext_tearing_down = _signals.signal("appcontext-tearing-down")
appcontext_pushed = _signals.signal("appcontext-pushed")
appcontext_popped = _signals.signal("appcontext-popped")
message_flashed = _signals.signal("message-flashed")

内置信号说明

内置信号会自动触发

request_started = _signals.signal('request-started')                # 请求到来前执行
request_finished = _signals.signal('request-finished')              # 请求结束后执行before_render_template = _signals.signal('before-render-template')  # 模板渲染前执行
template_rendered = _signals.signal('template-rendered')            # 模板渲染后执行got_request_exception = _signals.signal('got-request-exception')    # 请求执行出现异常时执行request_tearing_down = _signals.signal('request-tearing-down')      # 请求执行完毕后自动执行(无论成功与否)
appcontext_tearing_down = _signals.signal('appcontext-tearing-down')# 应用上下文执行完毕后自动执行(无论成功与否)appcontext_pushed = _signals.signal('appcontext-pushed')            # 应用上下文push时执行
appcontext_popped = _signals.signal('appcontext-popped')            # 应用上下文pop时执行
message_flashed = _signals.signal('message-flashed')                # 调用flash在其中添加数据时,自动触发

 

内置信号的使用

使用步骤:

第一步:写个函数–必须接受一些参数
第二步:跟信号绑定
第三步:触发信号

from flask import Flask, render_template
from flask import signalsapp = Flask(__name__)# 内置信号使用步骤
# 第一步:写个函数
def render_before(*args,**kwargs):print(args)print(kwargs)print('模板要渲染了')# 第二步:跟信号绑定
signals.before_render_template.connect(render_before)# 第三步:触发信号 (内置信号,会自动触发)@app.route('/')
def index():print('index 执行了')return render_template('index.html', name='刘亦菲')if __name__ == '__main__':app.run()

 

自定义信号

不会自动触发,只能手动触发,通过send方法

第一步:定义信号
第二步:写个函数
第三步:跟信号绑定
第四步:触发信号—指定触发时给绑定函数传递的参数

from flask import Flask, render_template,request
from flask import signals
from flask.signals import _signalsapp = Flask(__name__)# 第一步:定义信号
xxx = _signals.signal('xxx')# 第二步:写个函数
def add(*args, **kwargs):print(args)print(kwargs)print('add执行了')# 第三步:跟信号绑定
xxx.connect(add)#第四步:触发信号
@app.route('/')
def index():xxx.send(request=request)print('index 执行了')return render_template('index.html', name='刘亦菲')if __name__ == '__main__':app.run()


http://www.ppmy.cn/news/63526.html

相关文章

案例|九江银行Zabbix监控系统实践

Zabbix监控平台建设历程 九江银行Zabbix监控系统实践,共分为三个部分: 1.Zabbix监控平台的建设历程 2.Zabbix实践经验分享 3.对未来监控的展望。 项目背景 建立新的一体化基础监控平台。为适应数字化转型的需要、新技术发展的需要及业务连续性的需…

做客《创新之路》,Tapdata 创始人唐建法对话央视著名主持人李雨霏,畅聊创业故事

在近期播出的《创新之路》访谈栏目中,Tapdata 创始人兼 CEO 唐建法(TJ)对话央视著名主持人李雨霏,从一个人的创业梦想,聊到一个优秀团队的创新、突破与成长之路;从大数据时代企业对数据需求的日益提升&…

vue_组件基础

单文件组件 Vue 单文件组件&#xff08;又名 *.vue 文件&#xff0c;缩写为 SFC&#xff09;是一种特殊的文件格式&#xff0c;它允许将 Vue 组件的模板、逻辑 与 样式封装在单个文件中 <template><h3>单文件组件</h3> </template><script> ex…

Transformer的位置编码

1. 什么是位置编码&#xff0c;为什么要使用位置编码 简单来说位置编码就是给一个句子中的每个token一个位置信息&#xff0c;通过位置编码可以明确token的前后顺序关系。 对任何语言来说&#xff0c;句子中词汇的顺序和位置都是非常重要的。它们定义了语法&#xff0c;从而定…

web集群,部署jpress应用

1.静态网页与动态网页的区别 静态网页&#xff1a; &#xff08;1&#xff09;请求响应信息&#xff0c;发送给客户端进行处理&#xff0c;由浏览器进行解析&#xff0c;显示页面称为静态页面。在网站设计中&#xff0c;纯粹html格式的网页&#xff08;包含图片&#xff0c;视…

第5章 分布式缓存中间件的配置及其调用定义

1 分布式缓存中间件的配置定义 1.1 Core.Configuration.CacheConfig namespace Core.Configuration { /// <summary> /// 【缓存配置--类】 /// <remarks> /// 摘要&#xff1a; /// 通过该类中的属性成员实例对“appsettings.json”文件中的1个指定缓存项(…

非科班自学一年拿大厂offer,关于大学,说几个感受

大家好&#xff0c;我是帅地。 最近知识星球的小伙伴经常有人来报喜秋招上岸的信息&#xff0c;其中有一位星球的小伙伴是帅地的亲学弟&#xff0c;并且非科班&#xff0c;但是只花了一年时间&#xff0c;在 0 实习的情况下&#xff0c;依然拿到了某大厂 offer&#xff08;学弟…

SuperMap GIS基础产品组件GIS FAQ集锦(2)

SuperMap GIS基础产品组件GIS FAQ集锦&#xff08;2&#xff09; 【iObjects for Spark】读取GDB参数该如何填写&#xff1f; 【解决办法】可参考以下示例&#xff1a; val GDB_params new util.HashMapString, java.io.Serializable GDB_params.put(FeatureRDDProviderParam…