nltcache 1.0.6__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- nltcache-1.0.6/PKG-INFO +219 -0
- nltcache-1.0.6/README.md +208 -0
- nltcache-1.0.6/pyproject.toml +13 -0
- nltcache-1.0.6/setup.cfg +4 -0
- nltcache-1.0.6/src/nltcache/__init__.py +26 -0
- nltcache-1.0.6/src/nltcache/_utils.py +30 -0
- nltcache-1.0.6/src/nltcache/box.py +66 -0
- nltcache-1.0.6/src/nltcache/core.py +97 -0
- nltcache-1.0.6/src/nltcache/disk.py +97 -0
- nltcache-1.0.6/src/nltcache.egg-info/PKG-INFO +219 -0
- nltcache-1.0.6/src/nltcache.egg-info/SOURCES.txt +12 -0
- nltcache-1.0.6/src/nltcache.egg-info/dependency_links.txt +1 -0
- nltcache-1.0.6/src/nltcache.egg-info/requires.txt +3 -0
- nltcache-1.0.6/src/nltcache.egg-info/top_level.txt +1 -0
nltcache-1.0.6/PKG-INFO
ADDED
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nltcache
|
|
3
|
+
Version: 1.0.6
|
|
4
|
+
Summary: nltcache
|
|
5
|
+
Author-email: niuliangtao <farfarfun@qq.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: cachebox==5.0.1
|
|
9
|
+
Requires-Dist: diskcache>=5.6.3
|
|
10
|
+
Requires-Dist: nltlog>=1.0.9
|
|
11
|
+
|
|
12
|
+
# funcache
|
|
13
|
+
|
|
14
|
+
一个简洁的 Python 函数缓存装饰器库,提供多种缓存策略,涵盖内存缓存、磁盘缓存和 Pickle 文件缓存。
|
|
15
|
+
|
|
16
|
+
## 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install funcache-tau
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
要求 Python >= 3.8。
|
|
23
|
+
|
|
24
|
+
## 快速开始
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from funcache import lru_cache
|
|
28
|
+
|
|
29
|
+
@lru_cache()
|
|
30
|
+
def fibonacci(n):
|
|
31
|
+
if n < 2:
|
|
32
|
+
return n
|
|
33
|
+
return fibonacci(n - 1) + fibonacci(n - 2)
|
|
34
|
+
|
|
35
|
+
print(fibonacci(50))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 内存缓存
|
|
39
|
+
|
|
40
|
+
基于 [cachebox](https://github.com/awolverp/cachebox) 实现,提供多种淘汰策略。
|
|
41
|
+
|
|
42
|
+
### cache
|
|
43
|
+
|
|
44
|
+
最简单的 LRU 缓存装饰器,默认 maxsize=1000,无需传参直接使用。
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from funcache import cache
|
|
48
|
+
|
|
49
|
+
@cache
|
|
50
|
+
def add(a, b):
|
|
51
|
+
return a + b
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### lru_cache
|
|
55
|
+
|
|
56
|
+
**LRU (Least Recently Used)** — 淘汰最久未被访问的缓存条目。
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from funcache import lru_cache
|
|
60
|
+
|
|
61
|
+
@lru_cache(maxsize=500)
|
|
62
|
+
def query(sql):
|
|
63
|
+
...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### ttl_cache
|
|
67
|
+
|
|
68
|
+
**TTL (Time To Live)** — 缓存条目在超过指定时间后自动过期。
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from funcache import ttl_cache
|
|
72
|
+
|
|
73
|
+
@ttl_cache(maxsize=1000, ttl=300) # 300 秒后过期
|
|
74
|
+
def get_config(key):
|
|
75
|
+
...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### vttl_cache
|
|
79
|
+
|
|
80
|
+
**VTTL (Virtual TTL)** — 与 TTL 类似,但采用惰性淘汰策略,仅在访问时检查并移除过期条目。
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from funcache import vttl_cache
|
|
84
|
+
|
|
85
|
+
@vttl_cache(maxsize=1000, ttl=60)
|
|
86
|
+
def get_status(service):
|
|
87
|
+
...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### lfu_cache
|
|
91
|
+
|
|
92
|
+
**LFU (Least Frequently Used)** — 淘汰访问次数最少的缓存条目。
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from funcache import lfu_cache
|
|
96
|
+
|
|
97
|
+
@lfu_cache(maxsize=1000)
|
|
98
|
+
def translate(word):
|
|
99
|
+
...
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### fifo_cache
|
|
103
|
+
|
|
104
|
+
**FIFO (First In First Out)** — 淘汰最早进入缓存的条目。
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from funcache import fifo_cache
|
|
108
|
+
|
|
109
|
+
@fifo_cache(maxsize=1000)
|
|
110
|
+
def process(data):
|
|
111
|
+
...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### rr_cache
|
|
115
|
+
|
|
116
|
+
**RR (Random Replacement)** — 随机淘汰一个缓存条目。
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from funcache import rr_cache
|
|
120
|
+
|
|
121
|
+
@rr_cache(maxsize=1000)
|
|
122
|
+
def compute(x):
|
|
123
|
+
...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 磁盘缓存
|
|
127
|
+
|
|
128
|
+
### disk_cache
|
|
129
|
+
|
|
130
|
+
基于 [diskcache](https://github.com/grantjenks/python-diskcache) 实现,将缓存持久化到本地磁盘,支持过期时间,适用于需要跨进程或重启后保留缓存的场景。
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from funcache import disk_cache
|
|
134
|
+
|
|
135
|
+
@disk_cache(cache_key="query", expire=3600) # 缓存 1 小时
|
|
136
|
+
def search(query):
|
|
137
|
+
# 耗时的搜索操作
|
|
138
|
+
...
|
|
139
|
+
|
|
140
|
+
search("python cache") # 首次执行,结果写入磁盘
|
|
141
|
+
search("python cache") # 命中缓存,直接返回
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**参数说明:**
|
|
145
|
+
|
|
146
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
147
|
+
|------|------|--------|------|
|
|
148
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
149
|
+
| `cache_dir` | `str \| None` | `None` | 缓存目录,为 None 时自动生成 |
|
|
150
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
151
|
+
| `expire` | `int` | `86400` | 缓存过期时间(秒),默认 1 天 |
|
|
152
|
+
|
|
153
|
+
通过 `is_cache` 参数可以在运行时动态控制是否使用缓存:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
@disk_cache(cache_key="sql", is_cache="use_cache")
|
|
157
|
+
def run_query(sql, use_cache=True):
|
|
158
|
+
...
|
|
159
|
+
|
|
160
|
+
run_query("SELECT ...", use_cache=False) # 跳过缓存,直接执行
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Pickle 文件缓存
|
|
164
|
+
|
|
165
|
+
### pkl_cache
|
|
166
|
+
|
|
167
|
+
将函数结果序列化为 `.pkl` 文件存储到本地,适用于需要简单持久缓存但不想引入额外数据库的场景。
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from funcache import pkl_cache
|
|
171
|
+
|
|
172
|
+
@pkl_cache(cache_key="filepath", cache_dir=".my_cache")
|
|
173
|
+
def parse_file(filepath):
|
|
174
|
+
# 耗时的文件解析操作
|
|
175
|
+
...
|
|
176
|
+
|
|
177
|
+
parse_file("/data/large.csv") # 首次执行,结果写入 .pkl 文件
|
|
178
|
+
parse_file("/data/large.csv") # 命中缓存
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**参数说明:**
|
|
182
|
+
|
|
183
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
184
|
+
|------|------|--------|------|
|
|
185
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
186
|
+
| `cache_dir` | `str` | `".cache"` | 存储 pkl 文件的目录 |
|
|
187
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
188
|
+
| `printf` | `bool` | `False` | 是否将缓存日志输出到 stdout |
|
|
189
|
+
|
|
190
|
+
## 其他
|
|
191
|
+
|
|
192
|
+
### cached_property
|
|
193
|
+
|
|
194
|
+
重新导出自标准库 `functools.cached_property`,将方法结果缓存为实例属性。
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from funcache import cached_property
|
|
198
|
+
|
|
199
|
+
class Config:
|
|
200
|
+
@cached_property
|
|
201
|
+
def settings(self):
|
|
202
|
+
# 仅在首次访问时执行
|
|
203
|
+
return load_settings()
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## API 一览
|
|
207
|
+
|
|
208
|
+
| 装饰器 | 存储位置 | 淘汰策略 | 支持过期 |
|
|
209
|
+
|--------|---------|---------|---------|
|
|
210
|
+
| `cache` | 内存 | LRU | - |
|
|
211
|
+
| `lru_cache` | 内存 | LRU | - |
|
|
212
|
+
| `lfu_cache` | 内存 | LFU | - |
|
|
213
|
+
| `fifo_cache` | 内存 | FIFO | - |
|
|
214
|
+
| `rr_cache` | 内存 | 随机 | - |
|
|
215
|
+
| `ttl_cache` | 内存 | TTL | 是 |
|
|
216
|
+
| `vttl_cache` | 内存 | VTTL (惰性) | 是 |
|
|
217
|
+
| `disk_cache` | 磁盘 | - | 是 |
|
|
218
|
+
| `pkl_cache` | 磁盘 (pkl) | - | - |
|
|
219
|
+
| `cached_property` | 实例属性 | - | - |
|
nltcache-1.0.6/README.md
ADDED
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
# funcache
|
|
2
|
+
|
|
3
|
+
一个简洁的 Python 函数缓存装饰器库,提供多种缓存策略,涵盖内存缓存、磁盘缓存和 Pickle 文件缓存。
|
|
4
|
+
|
|
5
|
+
## 安装
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
pip install funcache-tau
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
要求 Python >= 3.8。
|
|
12
|
+
|
|
13
|
+
## 快速开始
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
from funcache import lru_cache
|
|
17
|
+
|
|
18
|
+
@lru_cache()
|
|
19
|
+
def fibonacci(n):
|
|
20
|
+
if n < 2:
|
|
21
|
+
return n
|
|
22
|
+
return fibonacci(n - 1) + fibonacci(n - 2)
|
|
23
|
+
|
|
24
|
+
print(fibonacci(50))
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## 内存缓存
|
|
28
|
+
|
|
29
|
+
基于 [cachebox](https://github.com/awolverp/cachebox) 实现,提供多种淘汰策略。
|
|
30
|
+
|
|
31
|
+
### cache
|
|
32
|
+
|
|
33
|
+
最简单的 LRU 缓存装饰器,默认 maxsize=1000,无需传参直接使用。
|
|
34
|
+
|
|
35
|
+
```python
|
|
36
|
+
from funcache import cache
|
|
37
|
+
|
|
38
|
+
@cache
|
|
39
|
+
def add(a, b):
|
|
40
|
+
return a + b
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### lru_cache
|
|
44
|
+
|
|
45
|
+
**LRU (Least Recently Used)** — 淘汰最久未被访问的缓存条目。
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from funcache import lru_cache
|
|
49
|
+
|
|
50
|
+
@lru_cache(maxsize=500)
|
|
51
|
+
def query(sql):
|
|
52
|
+
...
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### ttl_cache
|
|
56
|
+
|
|
57
|
+
**TTL (Time To Live)** — 缓存条目在超过指定时间后自动过期。
|
|
58
|
+
|
|
59
|
+
```python
|
|
60
|
+
from funcache import ttl_cache
|
|
61
|
+
|
|
62
|
+
@ttl_cache(maxsize=1000, ttl=300) # 300 秒后过期
|
|
63
|
+
def get_config(key):
|
|
64
|
+
...
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### vttl_cache
|
|
68
|
+
|
|
69
|
+
**VTTL (Virtual TTL)** — 与 TTL 类似,但采用惰性淘汰策略,仅在访问时检查并移除过期条目。
|
|
70
|
+
|
|
71
|
+
```python
|
|
72
|
+
from funcache import vttl_cache
|
|
73
|
+
|
|
74
|
+
@vttl_cache(maxsize=1000, ttl=60)
|
|
75
|
+
def get_status(service):
|
|
76
|
+
...
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
### lfu_cache
|
|
80
|
+
|
|
81
|
+
**LFU (Least Frequently Used)** — 淘汰访问次数最少的缓存条目。
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from funcache import lfu_cache
|
|
85
|
+
|
|
86
|
+
@lfu_cache(maxsize=1000)
|
|
87
|
+
def translate(word):
|
|
88
|
+
...
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### fifo_cache
|
|
92
|
+
|
|
93
|
+
**FIFO (First In First Out)** — 淘汰最早进入缓存的条目。
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
from funcache import fifo_cache
|
|
97
|
+
|
|
98
|
+
@fifo_cache(maxsize=1000)
|
|
99
|
+
def process(data):
|
|
100
|
+
...
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### rr_cache
|
|
104
|
+
|
|
105
|
+
**RR (Random Replacement)** — 随机淘汰一个缓存条目。
|
|
106
|
+
|
|
107
|
+
```python
|
|
108
|
+
from funcache import rr_cache
|
|
109
|
+
|
|
110
|
+
@rr_cache(maxsize=1000)
|
|
111
|
+
def compute(x):
|
|
112
|
+
...
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
## 磁盘缓存
|
|
116
|
+
|
|
117
|
+
### disk_cache
|
|
118
|
+
|
|
119
|
+
基于 [diskcache](https://github.com/grantjenks/python-diskcache) 实现,将缓存持久化到本地磁盘,支持过期时间,适用于需要跨进程或重启后保留缓存的场景。
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
from funcache import disk_cache
|
|
123
|
+
|
|
124
|
+
@disk_cache(cache_key="query", expire=3600) # 缓存 1 小时
|
|
125
|
+
def search(query):
|
|
126
|
+
# 耗时的搜索操作
|
|
127
|
+
...
|
|
128
|
+
|
|
129
|
+
search("python cache") # 首次执行,结果写入磁盘
|
|
130
|
+
search("python cache") # 命中缓存,直接返回
|
|
131
|
+
```
|
|
132
|
+
|
|
133
|
+
**参数说明:**
|
|
134
|
+
|
|
135
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
136
|
+
|------|------|--------|------|
|
|
137
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
138
|
+
| `cache_dir` | `str \| None` | `None` | 缓存目录,为 None 时自动生成 |
|
|
139
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
140
|
+
| `expire` | `int` | `86400` | 缓存过期时间(秒),默认 1 天 |
|
|
141
|
+
|
|
142
|
+
通过 `is_cache` 参数可以在运行时动态控制是否使用缓存:
|
|
143
|
+
|
|
144
|
+
```python
|
|
145
|
+
@disk_cache(cache_key="sql", is_cache="use_cache")
|
|
146
|
+
def run_query(sql, use_cache=True):
|
|
147
|
+
...
|
|
148
|
+
|
|
149
|
+
run_query("SELECT ...", use_cache=False) # 跳过缓存,直接执行
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Pickle 文件缓存
|
|
153
|
+
|
|
154
|
+
### pkl_cache
|
|
155
|
+
|
|
156
|
+
将函数结果序列化为 `.pkl` 文件存储到本地,适用于需要简单持久缓存但不想引入额外数据库的场景。
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
from funcache import pkl_cache
|
|
160
|
+
|
|
161
|
+
@pkl_cache(cache_key="filepath", cache_dir=".my_cache")
|
|
162
|
+
def parse_file(filepath):
|
|
163
|
+
# 耗时的文件解析操作
|
|
164
|
+
...
|
|
165
|
+
|
|
166
|
+
parse_file("/data/large.csv") # 首次执行,结果写入 .pkl 文件
|
|
167
|
+
parse_file("/data/large.csv") # 命中缓存
|
|
168
|
+
```
|
|
169
|
+
|
|
170
|
+
**参数说明:**
|
|
171
|
+
|
|
172
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
173
|
+
|------|------|--------|------|
|
|
174
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
175
|
+
| `cache_dir` | `str` | `".cache"` | 存储 pkl 文件的目录 |
|
|
176
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
177
|
+
| `printf` | `bool` | `False` | 是否将缓存日志输出到 stdout |
|
|
178
|
+
|
|
179
|
+
## 其他
|
|
180
|
+
|
|
181
|
+
### cached_property
|
|
182
|
+
|
|
183
|
+
重新导出自标准库 `functools.cached_property`,将方法结果缓存为实例属性。
|
|
184
|
+
|
|
185
|
+
```python
|
|
186
|
+
from funcache import cached_property
|
|
187
|
+
|
|
188
|
+
class Config:
|
|
189
|
+
@cached_property
|
|
190
|
+
def settings(self):
|
|
191
|
+
# 仅在首次访问时执行
|
|
192
|
+
return load_settings()
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
## API 一览
|
|
196
|
+
|
|
197
|
+
| 装饰器 | 存储位置 | 淘汰策略 | 支持过期 |
|
|
198
|
+
|--------|---------|---------|---------|
|
|
199
|
+
| `cache` | 内存 | LRU | - |
|
|
200
|
+
| `lru_cache` | 内存 | LRU | - |
|
|
201
|
+
| `lfu_cache` | 内存 | LFU | - |
|
|
202
|
+
| `fifo_cache` | 内存 | FIFO | - |
|
|
203
|
+
| `rr_cache` | 内存 | 随机 | - |
|
|
204
|
+
| `ttl_cache` | 内存 | TTL | 是 |
|
|
205
|
+
| `vttl_cache` | 内存 | VTTL (惰性) | 是 |
|
|
206
|
+
| `disk_cache` | 磁盘 | - | 是 |
|
|
207
|
+
| `pkl_cache` | 磁盘 (pkl) | - | - |
|
|
208
|
+
| `cached_property` | 实例属性 | - | - |
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "nltcache"
|
|
3
|
+
version = "1.0.6"
|
|
4
|
+
description = "nltcache"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.8"
|
|
7
|
+
dependencies = [ "cachebox==5.0.1", "diskcache>=5.6.3", "nltlog>=1.0.9",]
|
|
8
|
+
[[project.authors]]
|
|
9
|
+
name = "niuliangtao"
|
|
10
|
+
email = "farfarfun@qq.com"
|
|
11
|
+
|
|
12
|
+
[tool.setuptools]
|
|
13
|
+
license-files = []
|
nltcache-1.0.6/setup.cfg
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
from .box import (
|
|
2
|
+
cache,
|
|
3
|
+
fifo_cache,
|
|
4
|
+
lfu_cache,
|
|
5
|
+
lru_cache,
|
|
6
|
+
rr_cache,
|
|
7
|
+
ttl_cache,
|
|
8
|
+
vttl_cache,
|
|
9
|
+
)
|
|
10
|
+
from .core import PickleCache, cached_property, pkl_cache
|
|
11
|
+
from .disk import DiskCache, disk_cache
|
|
12
|
+
|
|
13
|
+
__all__ = [
|
|
14
|
+
"cache",
|
|
15
|
+
"lru_cache",
|
|
16
|
+
"ttl_cache",
|
|
17
|
+
"vttl_cache",
|
|
18
|
+
"lfu_cache",
|
|
19
|
+
"fifo_cache",
|
|
20
|
+
"rr_cache",
|
|
21
|
+
"PickleCache",
|
|
22
|
+
"pkl_cache",
|
|
23
|
+
"cached_property",
|
|
24
|
+
"disk_cache",
|
|
25
|
+
"DiskCache",
|
|
26
|
+
]
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
"""Internal utilities shared across funcache modules."""
|
|
2
|
+
|
|
3
|
+
import inspect
|
|
4
|
+
import os
|
|
5
|
+
from typing import Any, Callable, Dict, Tuple
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
def normalize_args(
|
|
9
|
+
func: Callable, args: Tuple[Any, ...], kwargs: Dict[str, Any]
|
|
10
|
+
) -> Dict[str, Any]:
|
|
11
|
+
"""Convert positional arguments to keyword arguments based on function signature.
|
|
12
|
+
|
|
13
|
+
This merges positional args into a unified kwargs dict for consistent
|
|
14
|
+
cache key lookup by parameter name.
|
|
15
|
+
"""
|
|
16
|
+
merged = dict(kwargs)
|
|
17
|
+
params = list(inspect.signature(func).parameters.items())
|
|
18
|
+
for i, (name, param) in enumerate(params):
|
|
19
|
+
if name not in merged:
|
|
20
|
+
merged[name] = args[i] if i < len(args) else param.default
|
|
21
|
+
return merged
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
def ensure_gitignore(directory: str) -> None:
|
|
25
|
+
"""Create a .gitignore with '*' in the given directory if one doesn't exist."""
|
|
26
|
+
os.makedirs(directory, exist_ok=True)
|
|
27
|
+
ignore_file = os.path.join(directory, ".gitignore")
|
|
28
|
+
if not os.path.exists(ignore_file):
|
|
29
|
+
with open(ignore_file, "w") as f:
|
|
30
|
+
f.write("*")
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
from typing import Callable
|
|
2
|
+
|
|
3
|
+
from cachebox import FIFOCache, LFUCache, LRUCache, RRCache, TTLCache, VTTLCache, cached
|
|
4
|
+
|
|
5
|
+
__all__ = [
|
|
6
|
+
"cache",
|
|
7
|
+
"lru_cache",
|
|
8
|
+
"ttl_cache",
|
|
9
|
+
"vttl_cache",
|
|
10
|
+
"lfu_cache",
|
|
11
|
+
"fifo_cache",
|
|
12
|
+
"rr_cache",
|
|
13
|
+
]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
def cache(func: Callable, /) -> Callable:
|
|
17
|
+
"""Simple LRU cache decorator with a default maxsize of 1000."""
|
|
18
|
+
return cached(LRUCache(maxsize=1000))(func)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def vttl_cache(maxsize: int = 1000, ttl: int = 60) -> Callable:
|
|
22
|
+
"""VTTLCache: removes expired elements lazily when accessed.
|
|
23
|
+
|
|
24
|
+
VTTLCache: 在访问时才惰性移除已过期的缓存元素。
|
|
25
|
+
"""
|
|
26
|
+
return lambda func: cached(VTTLCache(maxsize=maxsize, ttl=ttl))(func)
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
def ttl_cache(maxsize: int = 1000, ttl: int = 60) -> Callable:
|
|
30
|
+
"""TTLCache: automatically removes expired elements.
|
|
31
|
+
|
|
32
|
+
TTLCache:自动移除已过期的缓存元素。
|
|
33
|
+
"""
|
|
34
|
+
return lambda func: cached(TTLCache(maxsize=maxsize, ttl=ttl))(func)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def lru_cache(maxsize: int = 1000) -> Callable:
|
|
38
|
+
"""LRUCache: removes the least recently used element.
|
|
39
|
+
|
|
40
|
+
LRUCache:移除缓存中自上次访问以来时间最长的元素。
|
|
41
|
+
"""
|
|
42
|
+
return lambda func: cached(LRUCache(maxsize=maxsize))(func)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def lfu_cache(maxsize: int = 1000) -> Callable:
|
|
46
|
+
"""LFUCache: removes the least frequently used element.
|
|
47
|
+
|
|
48
|
+
LFUCache:移除缓存中访问次数最少的元素,不论其访问时间。
|
|
49
|
+
"""
|
|
50
|
+
return lambda func: cached(LFUCache(maxsize=maxsize))(func)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def fifo_cache(maxsize: int = 1000) -> Callable:
|
|
54
|
+
"""FIFOCache: removes the oldest element.
|
|
55
|
+
|
|
56
|
+
FIFOCache:移除在缓存中停留时间最长的元素。
|
|
57
|
+
"""
|
|
58
|
+
return lambda func: cached(FIFOCache(maxsize=maxsize))(func)
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
def rr_cache(maxsize: int = 1000) -> Callable:
|
|
62
|
+
"""RRCache: randomly removes an element when space is needed.
|
|
63
|
+
|
|
64
|
+
RRCache: 在必要时随机选择一个元素进行移除,以腾出空间。
|
|
65
|
+
"""
|
|
66
|
+
return lambda func: cached(RRCache(maxsize=maxsize))(func)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import hashlib
|
|
2
|
+
import os
|
|
3
|
+
import pickle
|
|
4
|
+
from functools import cached_property, wraps
|
|
5
|
+
from typing import Any, Callable, Optional
|
|
6
|
+
|
|
7
|
+
from funlog import getLogger
|
|
8
|
+
|
|
9
|
+
from ._utils import ensure_gitignore, normalize_args
|
|
10
|
+
|
|
11
|
+
logger = getLogger("funcache")
|
|
12
|
+
|
|
13
|
+
__all__ = ["PickleCache", "pkl_cache", "cached_property"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class PickleCache:
|
|
17
|
+
"""Decorator that caches function results to pickle files on disk.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
cache_key: The name of the function parameter whose value is used as the cache key.
|
|
21
|
+
cache_dir: Directory to store pickle cache files.
|
|
22
|
+
is_cache: The name of a boolean parameter that controls whether caching is enabled.
|
|
23
|
+
printf: If True, also print cache log messages to stdout.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
cache_key: str,
|
|
29
|
+
cache_dir: str = ".cache",
|
|
30
|
+
is_cache: str = "cache",
|
|
31
|
+
printf: bool = False,
|
|
32
|
+
) -> None:
|
|
33
|
+
self.cache_key = cache_key
|
|
34
|
+
self.cache_dir = cache_dir
|
|
35
|
+
self.is_cache = is_cache
|
|
36
|
+
self.printf = printf
|
|
37
|
+
|
|
38
|
+
def _log(self, msg: str) -> None:
|
|
39
|
+
if self.printf:
|
|
40
|
+
print(msg)
|
|
41
|
+
logger.debug(msg)
|
|
42
|
+
|
|
43
|
+
def _get_cache_file(self, key: str) -> str:
|
|
44
|
+
hashed = hashlib.md5(str(key).encode()).hexdigest()
|
|
45
|
+
return os.path.join(self.cache_dir, f"{hashed}.pkl")
|
|
46
|
+
|
|
47
|
+
@staticmethod
|
|
48
|
+
def _load_cache(cache_file: str) -> Optional[Any]:
|
|
49
|
+
try:
|
|
50
|
+
with open(cache_file, "rb") as f:
|
|
51
|
+
return pickle.load(f)
|
|
52
|
+
except (FileNotFoundError, pickle.PickleError):
|
|
53
|
+
return None
|
|
54
|
+
|
|
55
|
+
def _save_cache(self, cache_file: str, data: Any) -> None:
|
|
56
|
+
ensure_gitignore(self.cache_dir)
|
|
57
|
+
with open(cache_file, "wb") as f:
|
|
58
|
+
pickle.dump(data, f)
|
|
59
|
+
|
|
60
|
+
def __call__(self, func: Callable) -> Callable:
|
|
61
|
+
@wraps(func)
|
|
62
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
63
|
+
merged = normalize_args(func, args, kwargs)
|
|
64
|
+
|
|
65
|
+
is_cache = merged.get(self.is_cache, True)
|
|
66
|
+
cache_key = merged.get(self.cache_key, "")
|
|
67
|
+
is_cache = is_cache and cache_key is not None
|
|
68
|
+
|
|
69
|
+
if is_cache:
|
|
70
|
+
cache_file = self._get_cache_file(cache_key)
|
|
71
|
+
cached_result = self._load_cache(cache_file)
|
|
72
|
+
if cached_result is not None:
|
|
73
|
+
self._log(
|
|
74
|
+
f"Cache hit for function '{func.__name__}' with key: {cache_key}"
|
|
75
|
+
)
|
|
76
|
+
return cached_result
|
|
77
|
+
|
|
78
|
+
result = func(**merged)
|
|
79
|
+
|
|
80
|
+
if is_cache:
|
|
81
|
+
self._save_cache(cache_file, result)
|
|
82
|
+
self._log(
|
|
83
|
+
f"Cache data for function '{func.__name__}' with key: {cache_key}"
|
|
84
|
+
)
|
|
85
|
+
return result
|
|
86
|
+
|
|
87
|
+
return wrapper
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
def pkl_cache(
|
|
91
|
+
cache_key: str,
|
|
92
|
+
cache_dir: str = ".cache",
|
|
93
|
+
is_cache: str = "cache",
|
|
94
|
+
printf: bool = False,
|
|
95
|
+
) -> PickleCache:
|
|
96
|
+
"""Convenience factory for :class:`PickleCache`."""
|
|
97
|
+
return PickleCache(cache_key, cache_dir, is_cache, printf=printf)
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
import os
|
|
2
|
+
from functools import wraps
|
|
3
|
+
from hashlib import md5
|
|
4
|
+
from typing import Any, Callable, Optional
|
|
5
|
+
|
|
6
|
+
from diskcache import Cache
|
|
7
|
+
from funlog import getLogger
|
|
8
|
+
|
|
9
|
+
from ._utils import ensure_gitignore, normalize_args
|
|
10
|
+
|
|
11
|
+
logger = getLogger("funcache")
|
|
12
|
+
|
|
13
|
+
__all__ = ["DiskCache", "disk_cache"]
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class DiskCache:
|
|
17
|
+
"""Decorator that caches function results using :class:`diskcache.Cache`.
|
|
18
|
+
|
|
19
|
+
Args:
|
|
20
|
+
cache_key: The name of the function parameter whose value is used as the cache key.
|
|
21
|
+
cache_dir: Directory for the disk cache. Auto-generated from the function if *None*.
|
|
22
|
+
is_cache: The name of a boolean parameter that controls whether caching is enabled.
|
|
23
|
+
expire: Cache entry expiration time in seconds (default: 1 day).
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
def __init__(
|
|
27
|
+
self,
|
|
28
|
+
cache_key: str,
|
|
29
|
+
cache_dir: Optional[str] = None,
|
|
30
|
+
is_cache: str = "cache",
|
|
31
|
+
expire: int = 60 * 60 * 24,
|
|
32
|
+
) -> None:
|
|
33
|
+
self.cache_key = cache_key
|
|
34
|
+
self.cache_dir = cache_dir
|
|
35
|
+
self.is_cache = is_cache
|
|
36
|
+
self.expire = expire
|
|
37
|
+
self._cache: Optional[Cache] = None
|
|
38
|
+
|
|
39
|
+
def _init_cache(self, func: Callable) -> Cache:
|
|
40
|
+
if self._cache is not None:
|
|
41
|
+
return self._cache
|
|
42
|
+
|
|
43
|
+
if self.cache_dir is None:
|
|
44
|
+
uid = md5(func.__code__.co_filename.encode("utf-8")).hexdigest()
|
|
45
|
+
self.cache_dir = os.path.join(".disk_cache", f"{uid}-{func.__name__}")
|
|
46
|
+
|
|
47
|
+
self._cache = Cache(self.cache_dir)
|
|
48
|
+
ensure_gitignore(self.cache_dir)
|
|
49
|
+
|
|
50
|
+
logger.success(
|
|
51
|
+
f"init func {func.__name__} success. with cache_dir: {self.cache_dir}"
|
|
52
|
+
)
|
|
53
|
+
return self._cache
|
|
54
|
+
|
|
55
|
+
def __call__(self, func: Callable) -> Callable:
|
|
56
|
+
cache = self._init_cache(func)
|
|
57
|
+
|
|
58
|
+
@wraps(func)
|
|
59
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
|
60
|
+
merged = normalize_args(func, args, kwargs)
|
|
61
|
+
|
|
62
|
+
cache_key = merged.get(self.cache_key, "")
|
|
63
|
+
is_cache = merged.get(self.is_cache, True) and cache_key is not None
|
|
64
|
+
|
|
65
|
+
if not is_cache:
|
|
66
|
+
return func(**merged)
|
|
67
|
+
|
|
68
|
+
cached_result = cache.get(cache_key)
|
|
69
|
+
if cached_result is not None:
|
|
70
|
+
logger.debug(
|
|
71
|
+
f"Cache hit for function '{func.__name__}' with key: {cache_key}"
|
|
72
|
+
)
|
|
73
|
+
return cached_result
|
|
74
|
+
|
|
75
|
+
result = func(**merged)
|
|
76
|
+
cache.set(cache_key, result, expire=self.expire)
|
|
77
|
+
logger.debug(
|
|
78
|
+
f"Cache data for function '{func.__name__}' with key: {cache_key}"
|
|
79
|
+
)
|
|
80
|
+
return result
|
|
81
|
+
|
|
82
|
+
return wrapper
|
|
83
|
+
|
|
84
|
+
|
|
85
|
+
def disk_cache(
|
|
86
|
+
cache_key: str,
|
|
87
|
+
cache_dir: Optional[str] = None,
|
|
88
|
+
is_cache: str = "cache",
|
|
89
|
+
expire: int = 60 * 60 * 24,
|
|
90
|
+
) -> DiskCache:
|
|
91
|
+
"""Convenience factory for :class:`DiskCache`."""
|
|
92
|
+
return DiskCache(
|
|
93
|
+
cache_key=cache_key,
|
|
94
|
+
cache_dir=cache_dir,
|
|
95
|
+
is_cache=is_cache,
|
|
96
|
+
expire=expire,
|
|
97
|
+
)
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: nltcache
|
|
3
|
+
Version: 1.0.6
|
|
4
|
+
Summary: nltcache
|
|
5
|
+
Author-email: niuliangtao <farfarfun@qq.com>
|
|
6
|
+
Requires-Python: >=3.8
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
Requires-Dist: cachebox==5.0.1
|
|
9
|
+
Requires-Dist: diskcache>=5.6.3
|
|
10
|
+
Requires-Dist: nltlog>=1.0.9
|
|
11
|
+
|
|
12
|
+
# funcache
|
|
13
|
+
|
|
14
|
+
一个简洁的 Python 函数缓存装饰器库,提供多种缓存策略,涵盖内存缓存、磁盘缓存和 Pickle 文件缓存。
|
|
15
|
+
|
|
16
|
+
## 安装
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
pip install funcache-tau
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
要求 Python >= 3.8。
|
|
23
|
+
|
|
24
|
+
## 快速开始
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from funcache import lru_cache
|
|
28
|
+
|
|
29
|
+
@lru_cache()
|
|
30
|
+
def fibonacci(n):
|
|
31
|
+
if n < 2:
|
|
32
|
+
return n
|
|
33
|
+
return fibonacci(n - 1) + fibonacci(n - 2)
|
|
34
|
+
|
|
35
|
+
print(fibonacci(50))
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
## 内存缓存
|
|
39
|
+
|
|
40
|
+
基于 [cachebox](https://github.com/awolverp/cachebox) 实现,提供多种淘汰策略。
|
|
41
|
+
|
|
42
|
+
### cache
|
|
43
|
+
|
|
44
|
+
最简单的 LRU 缓存装饰器,默认 maxsize=1000,无需传参直接使用。
|
|
45
|
+
|
|
46
|
+
```python
|
|
47
|
+
from funcache import cache
|
|
48
|
+
|
|
49
|
+
@cache
|
|
50
|
+
def add(a, b):
|
|
51
|
+
return a + b
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
### lru_cache
|
|
55
|
+
|
|
56
|
+
**LRU (Least Recently Used)** — 淘汰最久未被访问的缓存条目。
|
|
57
|
+
|
|
58
|
+
```python
|
|
59
|
+
from funcache import lru_cache
|
|
60
|
+
|
|
61
|
+
@lru_cache(maxsize=500)
|
|
62
|
+
def query(sql):
|
|
63
|
+
...
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### ttl_cache
|
|
67
|
+
|
|
68
|
+
**TTL (Time To Live)** — 缓存条目在超过指定时间后自动过期。
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
from funcache import ttl_cache
|
|
72
|
+
|
|
73
|
+
@ttl_cache(maxsize=1000, ttl=300) # 300 秒后过期
|
|
74
|
+
def get_config(key):
|
|
75
|
+
...
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### vttl_cache
|
|
79
|
+
|
|
80
|
+
**VTTL (Virtual TTL)** — 与 TTL 类似,但采用惰性淘汰策略,仅在访问时检查并移除过期条目。
|
|
81
|
+
|
|
82
|
+
```python
|
|
83
|
+
from funcache import vttl_cache
|
|
84
|
+
|
|
85
|
+
@vttl_cache(maxsize=1000, ttl=60)
|
|
86
|
+
def get_status(service):
|
|
87
|
+
...
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### lfu_cache
|
|
91
|
+
|
|
92
|
+
**LFU (Least Frequently Used)** — 淘汰访问次数最少的缓存条目。
|
|
93
|
+
|
|
94
|
+
```python
|
|
95
|
+
from funcache import lfu_cache
|
|
96
|
+
|
|
97
|
+
@lfu_cache(maxsize=1000)
|
|
98
|
+
def translate(word):
|
|
99
|
+
...
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
### fifo_cache
|
|
103
|
+
|
|
104
|
+
**FIFO (First In First Out)** — 淘汰最早进入缓存的条目。
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
from funcache import fifo_cache
|
|
108
|
+
|
|
109
|
+
@fifo_cache(maxsize=1000)
|
|
110
|
+
def process(data):
|
|
111
|
+
...
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### rr_cache
|
|
115
|
+
|
|
116
|
+
**RR (Random Replacement)** — 随机淘汰一个缓存条目。
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
from funcache import rr_cache
|
|
120
|
+
|
|
121
|
+
@rr_cache(maxsize=1000)
|
|
122
|
+
def compute(x):
|
|
123
|
+
...
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
## 磁盘缓存
|
|
127
|
+
|
|
128
|
+
### disk_cache
|
|
129
|
+
|
|
130
|
+
基于 [diskcache](https://github.com/grantjenks/python-diskcache) 实现,将缓存持久化到本地磁盘,支持过期时间,适用于需要跨进程或重启后保留缓存的场景。
|
|
131
|
+
|
|
132
|
+
```python
|
|
133
|
+
from funcache import disk_cache
|
|
134
|
+
|
|
135
|
+
@disk_cache(cache_key="query", expire=3600) # 缓存 1 小时
|
|
136
|
+
def search(query):
|
|
137
|
+
# 耗时的搜索操作
|
|
138
|
+
...
|
|
139
|
+
|
|
140
|
+
search("python cache") # 首次执行,结果写入磁盘
|
|
141
|
+
search("python cache") # 命中缓存,直接返回
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
**参数说明:**
|
|
145
|
+
|
|
146
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
147
|
+
|------|------|--------|------|
|
|
148
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
149
|
+
| `cache_dir` | `str \| None` | `None` | 缓存目录,为 None 时自动生成 |
|
|
150
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
151
|
+
| `expire` | `int` | `86400` | 缓存过期时间(秒),默认 1 天 |
|
|
152
|
+
|
|
153
|
+
通过 `is_cache` 参数可以在运行时动态控制是否使用缓存:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
@disk_cache(cache_key="sql", is_cache="use_cache")
|
|
157
|
+
def run_query(sql, use_cache=True):
|
|
158
|
+
...
|
|
159
|
+
|
|
160
|
+
run_query("SELECT ...", use_cache=False) # 跳过缓存,直接执行
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
## Pickle 文件缓存
|
|
164
|
+
|
|
165
|
+
### pkl_cache
|
|
166
|
+
|
|
167
|
+
将函数结果序列化为 `.pkl` 文件存储到本地,适用于需要简单持久缓存但不想引入额外数据库的场景。
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
from funcache import pkl_cache
|
|
171
|
+
|
|
172
|
+
@pkl_cache(cache_key="filepath", cache_dir=".my_cache")
|
|
173
|
+
def parse_file(filepath):
|
|
174
|
+
# 耗时的文件解析操作
|
|
175
|
+
...
|
|
176
|
+
|
|
177
|
+
parse_file("/data/large.csv") # 首次执行,结果写入 .pkl 文件
|
|
178
|
+
parse_file("/data/large.csv") # 命中缓存
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
**参数说明:**
|
|
182
|
+
|
|
183
|
+
| 参数 | 类型 | 默认值 | 说明 |
|
|
184
|
+
|------|------|--------|------|
|
|
185
|
+
| `cache_key` | `str` | *必填* | 用作缓存键的函数参数名 |
|
|
186
|
+
| `cache_dir` | `str` | `".cache"` | 存储 pkl 文件的目录 |
|
|
187
|
+
| `is_cache` | `str` | `"cache"` | 控制是否启用缓存的布尔参数名 |
|
|
188
|
+
| `printf` | `bool` | `False` | 是否将缓存日志输出到 stdout |
|
|
189
|
+
|
|
190
|
+
## 其他
|
|
191
|
+
|
|
192
|
+
### cached_property
|
|
193
|
+
|
|
194
|
+
重新导出自标准库 `functools.cached_property`,将方法结果缓存为实例属性。
|
|
195
|
+
|
|
196
|
+
```python
|
|
197
|
+
from funcache import cached_property
|
|
198
|
+
|
|
199
|
+
class Config:
|
|
200
|
+
@cached_property
|
|
201
|
+
def settings(self):
|
|
202
|
+
# 仅在首次访问时执行
|
|
203
|
+
return load_settings()
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
## API 一览
|
|
207
|
+
|
|
208
|
+
| 装饰器 | 存储位置 | 淘汰策略 | 支持过期 |
|
|
209
|
+
|--------|---------|---------|---------|
|
|
210
|
+
| `cache` | 内存 | LRU | - |
|
|
211
|
+
| `lru_cache` | 内存 | LRU | - |
|
|
212
|
+
| `lfu_cache` | 内存 | LFU | - |
|
|
213
|
+
| `fifo_cache` | 内存 | FIFO | - |
|
|
214
|
+
| `rr_cache` | 内存 | 随机 | - |
|
|
215
|
+
| `ttl_cache` | 内存 | TTL | 是 |
|
|
216
|
+
| `vttl_cache` | 内存 | VTTL (惰性) | 是 |
|
|
217
|
+
| `disk_cache` | 磁盘 | - | 是 |
|
|
218
|
+
| `pkl_cache` | 磁盘 (pkl) | - | - |
|
|
219
|
+
| `cached_property` | 实例属性 | - | - |
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
src/nltcache/__init__.py
|
|
4
|
+
src/nltcache/_utils.py
|
|
5
|
+
src/nltcache/box.py
|
|
6
|
+
src/nltcache/core.py
|
|
7
|
+
src/nltcache/disk.py
|
|
8
|
+
src/nltcache.egg-info/PKG-INFO
|
|
9
|
+
src/nltcache.egg-info/SOURCES.txt
|
|
10
|
+
src/nltcache.egg-info/dependency_links.txt
|
|
11
|
+
src/nltcache.egg-info/requires.txt
|
|
12
|
+
src/nltcache.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
nltcache
|