zdppy+vue3+onlyoffice文档管理系统实战 20240822上课笔记 Python缓存框架的研究

基本用法

from zdppy_cache import Cache

# 创建缓存对象
cache = Cache()

# 关闭缓存对象
cache.close()

# 通过上下文自动关闭缓存对象
with Cache(cache.directory) as reference:
    reference.set('key', 'value')

# 通过缓存对象获取值
print(cache.get('key'))

指定缓存目录

from zdppy_cache import Cache

# 实例化缓存对象,指定缓存目录
cache = Cache('tmp/mycache')

# 设置缓存项
cache.set('key1', 'value1')

# 获取缓存项
value = cache.get('key1')
print('Cached value:', value)  # 输出: Cached value: value1

# 关闭缓存对象
cache.close()

删除缓存项

from zdppy_cache import Cache

# 实例化缓存对象,指定缓存目录
cache = Cache('tmp/mycache')

# 设置缓存项
cache.set('key1', 'value1')

# 删除指定的缓存项
cache.delete('key1')

# 验证缓存项是否已被删除
value = cache.get('key1')
print('Cached value:', value)  # 输出: Cached value: None

# 关闭缓存对象
cache.close()

判断键是否存在

from zdppy_cache import Cache

# 实例化缓存对象,指定缓存目录
cache = Cache('tmp/mycache')

# 设置缓存项
cache.set('key1', 'value1')

# 检查键是否存在
if 'key2' in cache:
    print("Key2 exists in cache")
else:
    print("Key2 does not exist in cache")

# 关闭缓存对象
cache.close()

设置过期时间

from zdppy_cache import Cache

# 实例化缓存对象,指定缓存目录
# cache = Cache('tmp/mycache')
cache = Cache()

# 设置缓存项,其中expire参数指定过期时间(单位:秒)
cache.set('key3', 'value3', expire=3)
print("没过期:", cache.get('key3'))

# 等待一段时间后尝试获取
import time

time.sleep(3)
value = cache.get('key3')
print('已经过期了:', value)  # 输出: Cached value after expiration: None

# 关闭缓存对象
cache.close()

手动清理缓存

from zdppy_cache import Cache

# 实例化缓存对象,指定缓存目录
# cache = Cache('tmp/mycache')
cache = Cache()

# 手动清理过期缓存
cache.expire()

# 定期清理可以结合定时任务或后台进程来实现

# 关闭缓存对象
cache.close()

自动清理缓存

from zdppy_cache import Cache

# DiskCache支持自动清理策略,如最少使用(LRU)清理,确保缓存的大小在控制范围内。
# 实例化缓存,指定大小限制为100MB
# DiskCache将自动管理缓存大小,根据LRU算法清理最少使用的缓存项
cache = Cache('tmp/mycache', size_limit=100 * 1024 * 1024)

# 关闭缓存对象
cache.close()

缓存函数

from zdppy_cache import Cache

# DiskCache支持自动清理策略,如最少使用(LRU)清理,确保缓存的大小在控制范围内。
# 实例化缓存,指定大小限制为100MB
# DiskCache将自动管理缓存大小,根据LRU算法清理最少使用的缓存项
cache = Cache('tmp/mycache', size_limit=100 * 1024 * 1024)


# DiskCache提供了装饰器,可以非常方便地缓存特定函数的返回结果,减少重复计算。
# 使用lru_cache装饰器自动缓存函数结果
@cache.memoize()
def compute_expensive_operation(x):
    # 模拟耗时计算
    return x * x * x


# 第一次调用,计算结果并缓存
result = compute_expensive_operation(3)
print(result)  # 输出: 27

# 第二次调用,直接从缓存获取结果
result = compute_expensive_operation(3)
print(result)  # 输出: 27

# 关闭缓存对象
cache.close()

并发安全

import threading

from zdppy_cache import Cache

# DiskCache支持自动清理策略,如最少使用(LRU)清理,确保缓存的大小在控制范围内。
# 实例化缓存,指定大小限制为100MB
# DiskCache将自动管理缓存大小,根据LRU算法清理最少使用的缓存项
cache = Cache('tmp/mycache', size_limit=100 * 1024 * 1024)


def cache_operations():
    cache.set('key', 'value')
    print('Cached:', cache.get('key'))


# DiskCache是线程安全和进程安全的,可以在多线程和多进程环境中安全使用。
# 在多线程环境下使用缓存
thread1 = threading.Thread(target=cache_operations)
thread2 = threading.Thread(target=cache_operations)
thread1.start()
thread2.start()
thread1.join()
thread2.join()

# 关闭缓存对象
cache.close()

缓存到底是怎么实现的

执行缓存的函数如下:

with Cache(cache.directory) as reference:
    reference.set('key', 'value')

所以,缓存的逻辑都在这个set方法里面。

在这里插入图片描述

set方法的完整代码如下:

def set(
        self,
        key,
        value,
        expire=None,
        read=False,
        tag=None,
        retry=False,
):
    """
    设置key的缓存为value,类似于存储了一个字典的键值对
    当read为True时,value应该是一个类似文件的对象,以二进制模式打开以供读取。
    当数据库超时并且retry为False(默认)时引发Timeout错误。

    :param key: 键
    :param value: 值
    :param float expire: 超时时间,默认不超时。浮点数类型,单位是秒。
    :param bool read: 是否读取二进制文件,默认False
    :param str tag: 类似于给key进行分组,打标签
    :param bool retry: 是否重试,默认False
    :return: 成功返回True
    :raises Timeout: 超时抛出异常

    """
    # 记录开始时间
    now = time.time()
    # 存储key
    db_key, raw = self._disk.put(key)
    # 计算超时时间
    expire_time = None if expire is None else now + expire
    # 进行存储
    size, mode, filename, db_value = self._disk.store(value, read, key=key)
    # 对存储的结果,进行封装,是一个元组
    columns = (expire_time, tag, size, mode, filename, db_value)

    # The order of SELECT, UPDATE, and INSERT is important below.
    # 使用示例:
    # value = cache.get(key)
    # if value is None:
    #     value = expensive_calculation()
    #     cache.set(key, value)
    #
    # Cache.get 不清理过期的键以避免查找期间的写操作。
    # 因此,常用/过期(used/expired)的键将保留在缓存中,使UPDATE成为首选路径。
    # 另一种方法是假设键不存在,首先尝试INSERT,然后处理由于违反UNIQUE约束而发生的IntegrityError。
    # 基于常见的缓存使用模式,这种乐观的方法被拒绝了。
    # INSERT OR REPLACE也就是UPSERT没有被使用,因为旧的文件名可能需要清理。

    with self._transact(retry, filename) as (sql, cleanup):
        # 执行SQL,获取结果
        rows = sql(
            'SELECT rowid, filename FROM Cache'
            ' WHERE key = ? AND raw = ?',
            (db_key, raw),
        ).fetchall()

        if rows:
            # 如果找到了,清理旧的数据,再执行更新
            ((rowid, old_filename),) = rows
            cleanup(old_filename)
            self._row_update(rowid, now, columns)
        else:
            # 如果没有找到,直接写入
            self._row_insert(db_key, raw, now, columns)

        # 计算是否超过缓存限制
        self._cull(now, sql, cleanup)

        # 成功了
        return True

下节课计划

封装一些简单的方法,比如:

  • set:设置缓存,带默认超时时间
  • get:获取缓存
  • delete:删除缓存
  • delete_all:清空缓存
  • 5
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Python私教

创业不易,请打赏支持我一点吧

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

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

打赏作者

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

抵扣说明:

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

余额充值