概述 📝
lazy_action 是一个功能强大且易于使用的 Python 函数缓存装饰器。它的核心目标是:将耗时函数的执行结果保存到磁盘上,当下次使用完全相同的参数调用该函数时,直接从磁盘缓存中读取结果,从而避免重复执行,极大地提升程序运行效率。
它底层使用了 diskcache 库,提供了持久化、自动管理的缓存能力。
核心功能 ✨
- 装饰器驱动: 只需在你的函数上添加一行
@lazy_action()即可启用缓存。 - 持久化缓存: 缓存结果保存在本地磁盘的
.lazy_action_cache文件夹中,即使程序重新启动,缓存依然有效。 - 智能缓存键: 自动根据函数所在的模块、函数名、位置参数和关键字参数生成唯一的缓存键,确保只有在输入完全相同时才命中缓存。
- 自动缓存管理: 能够自动创建、加载和清理缓存文件。
- 强大的容错性: 当检测到缓存文件损坏 (
DatabaseError) 或其他读写异常时,会自动重置并创建新的缓存,保证程序的健壮性。 - 支持缓存过期: 可以为缓存设置一个过期时间(TTL),过期后缓存将自动失效。
安装 📦
该库已发布到 PyPI,您可以使用 pip 轻松安装:
pip install lazy_action
安装过程会自动处理并安装其依赖库 (diskcache)。
如何使用 🚀
基础示例:
首先从库中导入 lazy_action 装饰器,并将其应用到你想要缓存结果的函数上。
import time
from lazy_action import lazy_action
# 使用装饰器,对 slow_function 的结果进行缓存
@lazy_action()
def slow_function(name):
print(f"函数正在执行... 为 '{name}' 进行复杂计算...")
time.sleep(3) # 模拟一个耗时3秒的操作
result = f"Hello, {name}!"
print("计算完成!")
return result
# --- 第一次调用 ---
start_time = time.time()
print(f"第一次调用的结果: {slow_function('World')}")
print(f"耗时: {time.time() - start_time:.2f} 秒\n")
# --- 第二次调用 (参数相同) ---
start_time = time.time()
print(f"第二次调用的结果: {slow_function('World')}") # 将直接从缓存读取
print(f"耗时: {time.time() - start_time:.2f} 秒\n")
输出结果:
lazy_action >> create cache folder
lazy_action >> cache reset to .lazy_action_cache/cache-1721554000.12345
函数正在执行... 为 'World' 进行复杂计算...
计算完成!
第一次调用的结果: Hello, World!
耗时: 3.01 秒
第二次调用的结果: Hello, World!
耗时: 0.00 秒
带过期时间的示例:
你可以给 lazy_action 传递一个 expire 参数(单位为秒),让缓存在指定时间后失效。
@lazy_action(expire=5) # 设置缓存5秒后过期
def get_data_from_remote():
print("正在从远程API获取数据...")
time.sleep(2)
return {"data": "some important data"}
get_data_from_remote() # 第一次执行,耗时2秒
get_data_from_remote() # 5秒内再次调用,直接返回缓存,耗时0秒
time.sleep(6)
get_data_from_remote() # 超过5秒,缓存失效,重新执行,耗时2秒
工作原理 ⚙️
-
缓存存储:
- 首次运行时,
lazy_action会在当前工作目录下创建一个名为.lazy_action_cache的隐藏文件夹。 - 在这个文件夹内部,它会创建一个以时间戳命名的子文件夹(如
cache-1721554000.12345),用于存放实际的缓存数据(由diskcache管理)。 - 程序再次启动时,会自动加载最新的那个缓存文件夹。
- 首次运行时,
-
缓存键生成:
- 为了确保缓存的唯一性和准确性,
lazy_action使用了一个复合键:(函数绝对路径, 函数名, 位置参数元组, 关键字参数元组)。 - 这意味着,即使两个不同文件中有同名函数,它们的缓存也是隔离的。参数的任何变化(包括顺序和值)都会导致缓存未命中。
- 为了确保缓存的唯一性和准确性,
-
核心逻辑 (
_get_or_run_and_set):- 当装饰的函数被调用时,它首先用上述规则生成缓存键。
- 检查该键是否存在于缓存中。
- 如果存在:直接返回缓存中的值。
- 如果不存在:执行原始函数,获取结果,将结果存入缓存,然后返回结果。
-
错误处理:
- 如果在任何读写缓存的环节(检查、获取、设置)发生异常,特别是
sqlite3.DatabaseError(表明底层数据库文件损坏),_reset_cache函数会被调用。 _reset_cache会清理掉所有旧的缓存实例,并创建一个全新的、干净的缓存目录,从而保证了即使在缓存损坏的情况下,程序也能继续正常运行(只是会暂时失去缓存效果)。
- 如果在任何读写缓存的环节(检查、获取、设置)发生异常,特别是
-
缓存目录
- 缓存目录默认为 当前目录的 ./lazy_action ,可以通过 LAZY_ACTION_FILE_PATH 环境变量修改。注意该目录必须存在,且可写。
Metadata
Release files for lazy-action 1.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| lazy_action-1.1.0.tar.gz | 13.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| lazy_action-1.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 22.7 kB
Release files / lazy_action-1.1.0.tar.gz
| Download URL | lazy_action-1.1.0.tar.gz |
|---|---|
| Size | 13.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
1248ea281aa0275de776d2a01fd20625bbed83dd59f3b7517905ba5babf9cecf
|
|
BLAKE2b-256 checksum How to use checksums |
c1e7f845612d46dab665d0683b33118049c912955e5a95a53869cd20dc1af261
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.11
|
Release files / lazy_action-1.1.0-py3-none-any.whl
| Download URL | lazy_action-1.1.0-py3-none-any.whl |
|---|---|
| Size | 8.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
ca43793322542dd3d670d9207e3b79178ac4ab02c75cc80a108053f4ee85153e
|
|
BLAKE2b-256 checksum How to use checksums |
a1cca04ded36510c73a0917a311bdfba7293fb69e9bb1ba83dd84738cfff188e
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.13.11
|