flask缓存、信号的使用

【 一 】flask-ache

​ 它为 Flask 应用程序提供了缓存支持。缓存是 Web 应用程序中非常常见的做法,用于存储频繁访问但不太可能经常更改的数据,以减少对数据库或其他慢速存储系统的访问,从而提高应用程序的性能和响应速度。

Flask-Caching 被配置为使用 SimpleCache 作为缓存后端。但是,SimpleCache 实际上并不适用于生产环境,因为它仅将缓存数据存储在内存中,并且不会跨多个服务器实例共享缓存数据。在生产环境中,你可能会使用更强大的缓存后端,如 Redis、Memcached 或数据库缓存。

  1. 设置缓存
    index 路由处理函数中,你使用 cache.set('name', 'xxx') 将键 'name' 与值 'xxx' 存储在缓存中。由于你设置了 CACHE_DEFAULT_TIMEOUT 为 300 秒,这个缓存条目将在大约 5 分钟后过期。
  2. 从缓存中获取数据
    get 路由处理函数中,你使用 cache.get('name') 从缓存中获取与键 'name' 关联的值。如果缓存中存在该键,则返回相应的值;否则,返回 None

Flask-Caching 的主要优点包括:

  • 性能提升:通过减少对数据库或其他慢速存储系统的访问,缓存可以显著提高应用程序的性能。
  • 减少数据库负载:对于频繁访问但不太可能经常更改的数据,缓存可以显著减少数据库的负载。
  • 易于配置和使用Flask-Caching 提供了多种缓存后端选项,并且易于配置和使用。
from flask import Flask
from flask_caching import Cache,SimpleCache

config = {
    "DEBUG": True,  # some Flask specific configs
    "CACHE_TYPE": "SimpleCache",  # Flask-Caching related configs ,可以缓存到redis
    "CACHE_DEFAULT_TIMEOUT": 300
}
app = Flask(__name__)
app.config.from_mapping(config)
cache = Cache(app)


@app.route('/')
def index():
    cache.set('name', '8888')
    return 'index'


@app.route('/get')
def get():
    res=cache.get('name')
    return res


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

# 1 跨域           flask-cors
# 2 jwt            flask-jwt
# 3 后台管理admin   flask-admin
# 4 前后端分离resful flask-resful

【 二 】信号

【 1 】Flask 信号机制的基本概念

  • 信号:在 Flask 中,信号是在应用程序中发生的某个事件,例如请求到达、请求处理完成或应用程序错误等。这些事件可以被视为应用程序生命周期中的关键点,开发人员可以在这些点上执行特定的操作。
  • 订阅-发布模式:Flask 的信号机制采用了订阅-发布模式。开发人员可以定义特定事件的处理函数(即订阅者),并在事件发生时执行这些函数(即发布事件)。这种机制使得开发人员能够在不修改核心应用逻辑的情况下,为应用程序添加额外的功能或行为。

【 2 】Flask 信号机制的工作原理

  • 定义信号:在 Flask 中,信号是通过 Blinker 库实现的。开发人员可以使用 Blinker 库或 Flask 提供的 flask.signals 模块来定义信号。信号通常被定义为一个命名空间(Namespace)下的属性,以便在应用程序中进行管理和引用。
  • 发送信号:当应用程序中的某个事件发生时,开发人员可以发送一个信号来通知所有订阅了该信号的函数。发送信号需要指定信号的名称以及要传递给订阅者的任何参数。
  • 接收信号:开发人员可以使用装饰器(如 @signal.connect)来定义处理特定信号的函数。这些函数将在信号被发送时自动执行,并可以接收从发送者传递过来的参数。

【 3 】信号的使用

  • Flask 提供了多个内置的信号,如请求开始、请求结束等,开发者也可以定义自己的信号。
  • 开发者可以在应用程序中注册一个或多个处理函数,这些函数会在信号被触发时执行。这些处理函数可以执行任何操作,如记录日志、发送邮件、更新数据库等。

【 4 】什么是信号

# 1 Flask框架中的信号基于blinker,其主要就是让开发者可以在flask请求过程中定制一些用户行为
# 2 信号是典型的 观察者模式
	-触发某个事执行【模板准备渲染】
    -绑定信号:可以绑定多个
    	只要模板准备渲染--》就会执行这几个绑定的新--》函数
        
        
# 3 面向切面编程(AOP)--》一种方案
	-整个程序正常运行,但是我们可以把一部分代码,插入到某个位置执行
    -钩子函数:只要写了,程序走到哪,就会执行,没写,就不会执行
    	-序列化类的校验
	
# 4 通过信号可以做什么事?
	-在框架整个执行过程中,插入一些代码执行
    	比如:记录某个页面的访问量
    	比如:每次渲染 login.html --->都记录日志
        比如:程序出异常---》记录日志
        比如:用户表中有个用户创建--》给这个用户发点短信
        比如:用户下了订单---》发个邮件通知,让它尽快付款
        
        比如:轮播图表只要发生变化,就删缓存:django中内置信号

【 5 】flask中内置信号的使用

###1 flask中内置信号
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')                # 调用flask在其中添加数据时,自动触发


###2 绑定内置信号,当程序执行到信号位置,就执行我们的函数



### 3 信号和请求扩展的关系
	-有的信号可以完成之前在请求扩展中完成的事
    -但他们机制不一样
    -信号更丰富
from flask import Flask, render_template, signals

app = Flask(__name__)
app.debug = True


###### 内置信号使用---》当模板渲染前[index.html]--》记录日志
# 1 写一个函数
def func1(*args, **kwargs):
    print('模板渲染了')
    print(args)
    print(kwargs.get('template').name)
    if 'index.html' == kwargs.get('template').name:
        print('记日志了')
    # from jinja2.environment import Template


# 2 跟内置信号绑定
signals.before_render_template.connect(func1)


# 3 等待触发(自动)


@app.route('/<string:name>')
def index(name):
    return render_template('index.html', name=name)


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


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

image-20240615195140649

image-20240615195014097

【 6 】flask自定义信号

# 步骤
# 0 定义一个自定义信号
# 1 写一个函数

# 2 跟内置信号绑定

# 3 等待触发(手动)-->只要blog_tag 插入一条记录,就触发

# pip install blinker
from dbutils.pooled_db import PooledDB
import pymysql
POOL = PooledDB(
    creator=pymysql,  # 使用链接数据库的模块
    maxconnections=6,  # 连接池允许的最大连接数,0和None表示不限制连接数
    mincached=2,  # 初始化时,链接池中至少创建的空闲的链接,0表示不创建
    maxcached=5,  # 链接池中最多闲置的链接,0和None不限制
    maxshared=3,
    # 链接池中最多共享的链接数量,0和None表示全部共享。PS: 无用,因为pymysql和MySQLdb等模块的 threadsafety都为1,所有值无论设置为多少,_maxcached永远为0,所以永远是所有链接都共享。
    blocking=True,  # 连接池中如果没有可用连接后,是否阻塞等待。True,等待;False,不等待然后报错
    maxusage=None,  # 一个链接最多被重复使用的次数,None表示无限制
    setsession=[],  # 开始会话前执行的命令列表。如:["set datestyle to ...", "set time zone ..."]
    ping=0,
    # ping MySQL服务端,检查是否服务可用。# 如:0 = None = never, 1 = default = whenever it is requested, 2 = when a cursor is created, 4 = when a query is executed, 7 = always
    host='127.0.0.1',
    port=3306,
    user='root',
    password='123123',
    database='school',
    charset='utf8'
)

from flask import Flask, request
import pymysql
from Pool import POOL

app = Flask(__name__)
app.debug = True


# 1 写一个函数,用于处理"info"的插入
def handle_info_insert(name, *args, **kwargs):
    print('处理info插入')
    if name == 'info':
        print('记录日志,info增加了')
        print(args)
        print(kwargs)

    # 3 等待触发(手动)-->只要info插入一条记录,就触发


def insert_data(sql, *args):
    # "模拟"发送信号,直接调用处理函数
    handle_info_insert('info', *args)
    conn = POOL.connection()
    cursor = conn.cursor(pymysql.cursors.DictCursor)
    cursor.execute(sql, args)  # 直接使用 args 元组作为 execute 的参数
    conn.commit()


@app.route('/info', methods=['GET'])
def create_tag():
    id = request.args.get('id', type=int)
    name = request.args.get('name')
    money = request.args.get('money')
    sql = "INSERT INTO info (id, name, money) VALUES (%s, %s, %s)"
    print(sql)
    insert_data(sql,  id,name, money)

    return '创建info数据成功!!!'


if __name__ == '__main__':
    app.run()
    
# http://127.0.0.1:5000/info?id=5&name=redis&money=588

image-20240615203504941

【 7 】django中信号的使用

## 1 内置信号
Model signals
    pre_init                    # django的modal执行其构造方法前,自动触发
    post_init                   # django的modal执行其构造方法后,自动触发
    pre_save                    # django的modal对象保存前,自动触发
    post_save                   # django的modal对象保存后,自动触发
    pre_delete                  # django的modal对象删除前,自动触发
    post_delete                 # django的modal对象删除后,自动触发
    m2m_changed                 # django的modal中使用m2m字段操作第三张表(add,remove,clear)前后,自动触发
    class_prepared              # 程序启动时,检测已注册的app中modal类,对于每一个类,自动触发
Management signals
    pre_migrate                 # 执行migrate命令前,自动触发
    post_migrate                # 执行migrate命令后,自动触发
Request/response signals
    request_started             # 请求到来前,自动触发
    request_finished            # 请求结束后,自动触发
    got_request_exception       # 请求异常后,自动触发
Test signals
    setting_changed             # 使用test测试修改配置文件时,自动触发
    template_rendered           # 使用test测试渲染模板时,自动触发
Database Wrappers
    connection_created          # 创建数据库连接时,自动触发
    
    
####### 内置信号使用##############
	1 写一个函数
    2 跟内置信号绑定
    3 等待触发(自动的)
    
   

## 1 写个函数
#放到__init__里
from django.db.models.signals import pre_save
import logging
def callBack(sender, **kwargs):
    # 过滤banner表   :kwargs就有表名
	print('对象保存了')
    # celery异步
    
# 2 绑定
post_save.connect(callBack)

# 3 绑定方式二,使用装饰器
from django.db.models.signals import pre_save
from django.dispatch import receiver
@receiver(pre_save)
def my_callback(sender, **kwargs):
    print("对象创建成功")
    print(sender)
    print(kwargs)


#### 自定义信号######
# 1 定义信号(一般创建一个py文件)(toppings,size 是接受的参数)
import django.dispatch
pizza_done = django.dispatch.Signal(providing_args=["toppings", "size"])

#2  写个函数注册信号
def callback(sender, **kwargs):
    print("callback")
    print(sender,kwargs)
pizza_done.connect(callback)

# 3 触发信号
from 路径 import pizza_done
pizza_done.send(sender='seven',toppings=123, size=456)

【 8 】用信号的好处

# 代码侵入性低---》解耦

【 9 】 信号和信号量

# 信号:signal 
	-flask,django中得 观察者模式  --》信号机制
    
# 信号量:Semaphore
	-并发编程中概念
    在Python中,信号量(Semaphore)主要用来控制多个线程或进程对共享资源的访问。信号量本质上是一种计数器的锁,它维护一个许可(permit)数量,每次 acquire() 函数被调用时,如果还有剩余的许可,则减少一个,并允许执行;如果没有剩余许可,则阻塞当前线程直到其他线程释放信号量

    
    
    
    
 
    

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/779735.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

一个 32 位程序的用户空间区域可以有多大?

缘起 我在《调试实战 | 记一次有教益的内存碎片转储文件分析》中分析了一个由于内存碎片导致的崩溃转储。发现一个很“奇怪”的现象——程序是 32 位的&#xff0c;但是在查看堆空间大小的时候&#xff0c;居然有将近 4GB。 相信各位小伙伴儿应该听过下面这种说法&#xff1a;…

力扣 第 134 场双周赛 解题报告 | 珂学家

前言 题解 T1/T3是环形的处理技巧&#xff0c;这边可以double数组(更准确地讲&#xff0c;添加一个合适的小尾巴). T4是典题&#xff0c;前不久周赛刚考过&#xff0c;是一道结论题&#xff0c;也可以借助数据结构处理。 T1. 交替组 I 和T3一起讲 T2. 与敌人战斗后的最大分数…

昇思25天学习打卡营第13天|K近邻算法实现红酒聚类

K近邻算法&#xff08;K-Nearest-Neighbor, KNN&#xff09;是一种用于分类和回归的非参数统计方法&#xff0c;是机器学习最基础的算法之一。它正是基于以上思想&#xff1a;要确定一个样本的类别&#xff0c;可以计算它与所有训练样本的距离&#xff0c;然后找出和该样本最接…

机器学习与现代医疗设备的结合:革新医疗健康的未来

&#x1f3ac; 鸽芷咕&#xff1a;个人主页 &#x1f525; 个人专栏: 《C干货基地》《粉丝福利》 ⛺️生活的理想&#xff0c;就是为了理想的生活! 引言 随着技术的不断进步&#xff0c;机器学习&#xff08;Machine Learning, ML&#xff09;在现代医疗设备中的应用正在改变着…

7.5cf

Problem - D - Codeforces 大致题目意思&#xff1a;找#的圆心 #include<bits/stdc.h> typedef long long ll;#define IOS ios::sync_with_stdio(0),cin.tie(0),cout.tie(0) const ll N1e21; char a[N][N]; using namespace std;int main() {IOS;int t;cin>>t;whi…

含并行连结的网络

一、Inception块 1、白色部分通过降低通道数来控制模型复杂度&#xff0c;蓝色做特征提取工作&#xff0c;每条路上的通道数可能不同&#xff0c;大概我们会把更重要的那部分特征分配更多的通道数 2、Inception只改变高宽&#xff0c;不改变通道数 3、在不同的情况下需要选择…

gitee项目上不同的项目分别使用不用的用户上传

最近使用根据需要&#xff0c;希望不同的项目使用不同的用户上传&#xff0c;让不同的仓库展示不同的用户名&#xff01;&#xff01;&#xff01; 第一步查看全局的用户信息&#xff1a; # 查看目前全局git配置信息 git config -l #会输出全局的git配置信息 第二步进入到要设…

【MySQL】1.初识MySQL

初识MySQL 一.MySQL 安装1.卸载已有的 MySQL2.获取官方 yum 源3.安装 MySQL4.登录 MySQL5.配置 my.cnf 二.MySQL 数据库基础1.MySQL 是什么&#xff1f;2.服务器&#xff0c;数据库和表3.mysqld 的层状结构4.SQL 语句分类 一.MySQL 安装 1.卸载已有的 MySQL //查询是否有相关…

【ubuntu】安装(升级)显卡驱动,黑屏|双屏无法使用问题解决方法

every blog every motto: You can do more than you think. https://blog.csdn.net/weixin_39190382?typeblog 0. 前言 ubuntu 安装(升级)显卡驱动&#xff0c;黑屏|双屏无法使用问题解决方法 由于项目需要&#xff0c;对显卡驱动进行升级。升级完就黑屏。。。。&#xff0…

平台稳定性里程碑 | Android 15 Beta 3 已发布

作者 / 产品管理副总裁、Android 开发者 Matthew McCullough 从近期发布的 Beta 3 开始&#xff0c;Android 15 达成了平台稳定性里程碑版本&#xff0c;这意味着开发者 API 和所有面向应用的行为都已是最终版本&#xff0c;您可以查阅它们并将其集成到您的应用中&#xff0c;并…

qt 开发笔记堆栈布局的应用

1.概要 画面中有一处位置&#xff0c;有个按钮点击后&#xff0c;这片位置完全换成另一个画面&#xff0c;这中情况特别适合用堆栈布局。 //堆栈布局的应用 #include <QStackedLayout> QStackedLayout *layout new QStackedLayout(this); layout->setCurrentIndex(…

无法下载cuda

cuda下载不了 一、台式机电脑浏览器打不开cuda下载下面二、解决办法 一、台式机电脑浏览器打不开cuda下载下面 用360、chrome、Edge浏览器都打不开下载页面&#xff0c;有的人说后缀com改成cn&#xff0c;都不行。知乎上说是网络问题&#xff0c;电信换成换成移动/联通的网络会…

文心一言最常用的20条指令及指令说明,含增强指令

下面是20条文心一言的指令及其说明&#xff0c;每条指令尽量简洁明了&#xff0c;以便在有限的字数内提供尽可能多的信息。以下是这些指令及其说明&#xff1a; 1. 查询天气 指令&#xff1a;今天北京的天气怎么样&#xff1f;说明&#xff1a;此指令用于查询特定城市&#xf…

Python结合MobileNetV2:图像识别分类系统实战

一、目录 算法模型介绍模型使用训练模型评估项目扩展 二、算法模型介绍 图像识别是计算机视觉领域的重要研究方向&#xff0c;它在人脸识别、物体检测、图像分类等领域有着广泛的应用。随着移动设备的普及和计算资源的限制&#xff0c;设计高效的图像识别算法变得尤为重要。…

数据结构基础--------【二叉树基础】

二叉树基础 二叉树是一种常见的数据结构&#xff0c;由节点组成&#xff0c;每个节点最多有两个子节点&#xff0c;左子节点和右子节点。二叉树可以用来表示许多实际问题&#xff0c;如计算机程序中的表达式、组织结构等。以下是一些二叉树的概念&#xff1a; 二叉树的深度&a…

高考选专业,兴趣与就业前景该如何平衡?

从高考结束的那一刻开始&#xff0c;有些家长和学生就已经变得焦虑了&#xff0c;因为他们不知道成绩出来的时候学生应该如何填报志愿&#xff0c;也不知道选择什么样的专业&#xff0c;毕竟大学里面的专业丰富多彩&#xff0c;如何选择确实是一门学问&#xff0c;而对于学生们…

Zynq7000系列FPGA中DMA引擎编程指南

DMA引擎的编程指南通常涉及一系列步骤和API调用&#xff0c;以确保数据在内存之间的高效传输&#xff0c;而无需CPU的直接干预。 DMA引擎的编程指南包括以下部分&#xff1a; 一、编写微代码为AXI事务编写CCRx程序 通道微码用于设置dmac.CCRx寄存器以定义AXI事务的属性。这是…

Node.js-path 模块

path 模块 path 模块提供了 操作路径 的功能&#xff0c;如下是几个较为常用的几个 API&#xff1a; 代码实例&#xff1a; const path require(path);//获取路径分隔符 console.log(path.sep);//拼接绝对路径 console.log(path.resolve(__dirname, test));//解析路径 let pa…

java反射介绍

Java反射API允许你在运行时检查和修改程序的行为。这意味着你可以动态地创建对象、查看类的字段、方法和构造函数&#xff0c;甚至调用它们。这是一个强大的特性&#xff0c;但也应该谨慎使用&#xff0c;因为它可以破坏封装性。 以下是使用Java反射的一些常见用途&#xff1a;…

041基于SSM+Jsp的高校校园点餐系统

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…