在以上类示例中没有包含什么特别之处。我们只是创建一个简单类,同时设置两个类变量或者说属性,即cahce与max_cache_size。其中cache属于一套空字典,而max_cache_size显然代表着最大缓存容量。下面让我们进一步充实该代码,使其具备一定功能:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import datetime
import random
########################################################################
class MyCache:
""""""
#----------------------------------------------------------------------
def __init__(self):
"""Constructor"""
self.cache = {}
self.max_cache_size = 10
#----------------------------------------------------------------------
def __contains__(self, key):
"""
根据该键是否存在于缓存当中返回True或者False
"""
return key in self.cache
#----------------------------------------------------------------------
def update(self, key, value):
"""
更新该缓存字典,您可选择性删除最早条目
"""
if key not in self.cache and len(self.cache) >= self.max_cache_size:
self.remove_oldest()
self.cache[key] = {'date_accessed': datetime.datetime.now(),
'value': value}
#----------------------------------------------------------------------
def remove_oldest(self):
"""
删除具备最早访问日期的输入数据
"""
oldest_entry = None
for key in self.cache:
if oldest_entry == None:
oldest_entry = key
elif self.cache[key]['date_accessed'] < self.cache[oldest_entry][
'date_accessed']:
oldest_entry = key
self.cache.pop(oldest_entry)
#----------------------------------------------------------------------
@property
def size(self):
"""
返回缓存容量大小
"""
return len(self.cache)
在这里,我们导入了datetime与random模块,而后我们即可看到之前创建完成的类。这一次,我们向其中添加几种方法。其中一种方法具备神奇的效果,名为_contains_。虽然在这里并不一定要使用该方法,但其基本思路在于允许我们检查该类实例,从而了解其中是否包含有我们正在寻找的键。另外,update方法负责利用新的键/值对进行缓存字典更新。一旦达到或者超出缓存最大容量,其还会删除日期最早的输入数据。另外,remove_oldest方法负责具体的字典内早期数据删除工作。最后,我们还引入了名为size的属性,其能够返回缓存的具体容量。
在添加了以下代码之后,我们就能够测试该缓存是否按预期起效:
if __name__ == ‘__main__’: #测试缓存 keys = [‘test’, ‘red’, ‘fox’, ‘fence’, ‘junk’, ‘other’, ‘alpha’, ‘bravo’, ‘cal’, ‘devo’, ‘ele’] s = ‘abcdefghijklmnop’ cache = MyCache() for i, key in enumerate(keys): if key in cache: continue else: value = ”.join([random.choice(s) for i in range(20)]) cache.update(key, value) print(“#%s iterations, #%s cached entries” % (i+1, cache.size)) print
在本示例当中,我们设置了大量预定义键与循环。如果键尚不存在,我们会将其添加到缓存当中。不过以上示例代码并没有提到如何更新访问日期,感兴趣的朋友们可以将其作为练习自行探索。在运行这段代码之后,大家会注意到当缓存被占满时,其会正确删除时间更早的条目。
现在,我们继续前进,看看如何利用另一种方式使用Python的内置functools模块创建缓存。