flask缓存、信号的使用

news2024/11/16 9:30:02

【 一 】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() 函数被调用时,如果还有剩余的许可,则减少一个,并允许执行;如果没有剩余许可,则阻塞当前线程直到其他线程释放信号量

    
    
    
    
 
    

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

程序员必知的 89 个操作系统核心概念

1. 操作系统&#xff08;Operating System&#xff0c;OS&#xff09;&#xff1a;是管理计算机硬件与软件资源的系统软件&#xff0c;同时也是计算机系统的内核与基石。操作系统需要处理管理与配置内存、决定系统资源供需的优先次序、控制输入与输出设备、操作网络与管理文件系…

Stable Diffusion 【模型推荐】没有最强,只有更强!高清画质!电影光效版SD1.5人像摄影大模型《他和她 2》

今天带来了一款SD1.5大模型——《他和她 2》电影光效版SD1.5人像摄影大模型。该模型经过家叔马丁Mr_M大佬的优化升级后&#xff0c;把SD1.5的影像光效推上了全新的高度&#xff01;根据大佬的描述&#xff0c;该模型具有更强大的细节表现&#xff0c;更细腻的表面肌理&#xff…

揭秘SmartEDA:电路仿真软件如何贯穿课前课中课后,助力电子学习新纪元!

在电子设计与自动化的学习道路上&#xff0c;一款强大的电路仿真软件往往能为学生们带来事半功倍的效果。今天&#xff0c;我们就来深入探讨一下SmartEDA这款电路仿真软件在课前、课中、课后的全方位应用&#xff0c;看看它如何助力我们的电子学习步入新纪元&#xff01; 1、课…

水果商城系统 SpringBoot+Vue

1、技术栈 技术栈&#xff1a;SpringBootVueMybatis等使用环境&#xff1a;Windows10 谷歌浏览器开发环境&#xff1a;jdk1.8 Maven mysql Idea 数据库仅供学习参考 【已经答辩过的毕业设计】 项目源码地址 2、功能划分 3、效果演示

下载安装JavaFX及解决报错:缺少 JavaFX 运行时组件, 需要使用该组件来运行此应用程序|Eclipse

目录 1.下载并解压 2.Eclipse配置 3.报错问题 解决方法1&#xff1a;将javaSE更改到9以下 解决方法2&#xff1a; 使用module-info.java配置解决 1.下载并解压 JavaFX下载地址&#xff1a;JavaFX - Gluon 选择合适自己电脑配置的sdk版本下载 打不开网页的参考这个博客&…

泛微开发修炼之旅--35关于基于页面扩展和自定义按钮实现与后端交互调用的方法

文章链接&#xff1a;35关于基于页面扩展和自定义按钮实现与后端交互调用的方法

【手写数据库内核组件】0201 哈希表hashtable的实战演练,多种非加密算法,hash桶的冲突处理,查找插入删除操作的代码实现

hash表原理与实战 ​专栏内容&#xff1a; postgresql使用入门基础手写数据库toadb并发编程 个人主页&#xff1a;我的主页 管理社区&#xff1a;开源数据库 座右铭&#xff1a;天行健&#xff0c;君子以自强不息&#xff1b;地势坤&#xff0c;君子以厚德载物. 文章目录 hash表…

如果国产BI工具也有顶流,它们一定会上榜

在数据驱动的今天&#xff0c;商业智能&#xff08;BI&#xff09;工具已成为企业不可或缺的助手&#xff0c;它们通过强大的数据处理和分析能力&#xff0c;帮助企业洞察市场趋势&#xff0c;优化运营决策。如果BI工具界也有“顶流”&#xff0c;那么奥威BI、帆软BI&#xff0…

世优科技获新锐商业价值奖,数字人阿央入选北京市元宇宙“名人”

2024全球经济大会元宇宙创新发展论坛暨2024第九届“创客中国”元宇宙中小企业创新创业大赛&#xff0c;由工业和信息化部网络安全产业发展中心、北京市经济和信息化局、石景山区人民政府、首钢集团有限公司主办&#xff0c;围绕元宇宙底层技术端和产业应用端两个方向&#xff0…

ROS2 分布式 及 ssh远程控制 和 上传下载文件或文件夹

问题1. 多台计算机连接同一wifi后 &#xff0c;运行ROS2的小乌龟案例&#xff0c;自己的计算机&#xff0c;无法控制其他电脑的小乌龟 按照正常的情况来说&#xff0c;ROS2是DDS的自发现通信机制&#xff0c;只要处在同一wifi网络中&#xff0c; A计算机执行启动小乌龟的命…

计算机网络-组播分发树与组播协议

一、组播分发树 前面我们大致了解了下组播的转发原理&#xff0c;通过RPF反向路径检查可以形成无环的组播转发路径&#xff0c;今天继续学习下组播分发树和组播协议。 组播数据转发需要保证转发路径无环&#xff0c;无次优路径且无重复包。通过RPF机制与组播路由协议&#xff0…

【撤稿资讯】国家杰青被撤稿23篇文章,主要原因图片重复使用等

本周投稿推荐 SCI • 能源科学类&#xff0c;1.5-2.0&#xff08;来稿即录25天&#xff09; • 计算机类&#xff0c;2.0-3.0&#xff08;纯正刊29天录用&#xff09; EI • 各领域沾边均可&#xff08;2天录用&#xff09; 知网 • 7天录用-检索&#xff08;急录友好&a…

论文图片模糊怎么办?科研绘图小track解决你的困扰

论文图片模糊怎么办&#xff1f;科研绘图小track解决你的困扰 一、 使用draw.io 绘图二、使用在线压缩工具&#xff0c;尽可能的无损压缩(推荐迅捷图片转换器)三、当然你也可以用svg 一、 使用draw.io 绘图 网址&#xff1a;https://draw.io/ 解决方法&#xff1a; 加大图片的分…

延时双删两种实现对比分析

前言 延时双删&#xff08;Delayed Double Deletion&#xff09;是一种在分布式系统或缓存一致性处理中使用的技术&#xff0c;目的是确保缓存与数据库之间的数据一致性。它主要用于处理在高并发情况下&#xff0c;缓存和数据库可能出现的数据不一致问题。 常见更新策略的问题…

5分钟微课视频制作方法 微课录制后期制作方法

微课视频是一种短小精悍的在线教育视频形式&#xff0c;通常时长在5到10分钟左右&#xff0c;观众可以在短暂的时间内获取到有用的信息。微课视频的目的是通过简洁明了的内容&#xff0c;向观众传递特定的知识点或技能&#xff0c;它的特点在于紧凑、便于消化和分享&#xff0c…

ESP32CAM物联网教学10

ESP32CAM物联网教学10 MicroPython 应用体验 小智偶然地发现&#xff0c;有一种新兴的编程模式MicroPython&#xff0c;也能编写ESP32Cam的应用程序了&#xff0c;于是欣然地体验了一把。 编程环境搭建 小智偶然地从下面这家店铺买了一块ESP32Cam&#xff0c;并从客服那里得到…

【人工智能】-- 智能家居

个人主页&#xff1a;欢迎来到 Papicatch的博客 课设专栏 &#xff1a;学生成绩管理系统 专业知识专栏&#xff1a; 专业知识 文章目录 &#x1f349;引言 &#x1f349;基于深度卷积神经网络的表情识别 &#x1f348;流程图 &#x1f348;模型设计 &#x1f34d;网络架…

安全防御(防火墙)

第二天&#xff1a; 1.恶意程序---一般会具有一下多个或则全部特点 1.非法性&#xff1a;你未经授权它自动运行或者自动下载的&#xff0c;这都属于非法的。那恶意程序一般它会具有这种特点&#xff0c; 2.隐蔽性&#xff1a;一般隐藏的会比较深&#xff0c;目的就是为了防止…

UML建模工具Draw.io简介

新书速览|《UML 2.5基础、建模与设计实践 Draw.io是一个非常出色的免费、开源、简洁、方便的绘图软件&#xff0c;利用这款软件可以绘制出生动有趣的图形&#xff0c;包括流程图、地图、网络架构图、UML用例图、流程图等。它支持各种快捷键&#xff0c;免费提供了1000多张画图…

80+ ChatGPT 文献综述指令

进行文献综述通常似乎是一项艰巨的任务。它是学术和研究工作的重要组成部分&#xff0c;涉及对先前发表的与特定主题相关的研究进行全面和批判性分析。目标是深入了解该主题的知识状况&#xff0c;找出差距&#xff0c;并为进一步研究奠定基础。 传统上&#xff0c;文献综述是…