import functools import time import weakref import collections class LocalCache(): class Dict(dict): def __del__(self): pass def __init__(self, maxlen=10): self.weak = weakref.WeakValueDictionary() # {'key1':{}, 'key2':{}, 'key3': {}} 內嵌的字典value弱引用self.strong裏面的字典元素 self.strong = collections.deque(maxlen=maxlen) # 隊列中的元素是字典對象 @staticmethod def nowTime(): return int(time.time()) def get(self, key): ''' 弱引用裏面取數據,強引用裏面刪除對象 ''' value = self.weak.get(key, None) if value is not None: expire = value[r'expire'] if self.nowTime() > expire: return else: return value else: return def set(self, key, value): # to-do 判斷key是否已經存在了、判斷key是不是可hash對象 self.weak[key] = strongRef = LocalCache.Dict(value) # 這行代碼是重點 self.strong.append(strongRef) # 閉包的一種使用場景 def funcCache(expire=0): caches = LocalCache() # 閉包的自由變量 def _wrappend(func): @functools.wraps(func) def __wrappend(*args, **kwargs): key = str(func) + str(args) + str(kwargs) # key是被裝飾函數的參數拼接 result = caches.get(key) if result is None: result = func(*args, **kwargs) caches.set(key, {'result': result, 'expire': expire + caches.nowTime()}) result = caches.get(key) return result return __wrappend return _wrappend @funcCache(expire=3) def test_cache(v): print('work 3s') return v print(test_cache(1)) print(test_cache(2)) print(test_cache(1)) # 參數爲1 在上面已經有調用過了,因此這個是從緩存中取的 print(test_cache(2)) # 參數爲2 在上面已經有調用過了,因此這個是從緩存中取的 # 測試緩存超時後(4s > 3s)的效果 print('\n緩存過時後的結果:') time.sleep(4) print(test_cache(1)) print(test_cache(2))
輸出結果php
work 3s {'result': 1, 'expire': 1626521912} work 3s {'result': 2, 'expire': 1626521912} {'result': 1, 'expire': 1626521912} {'result': 2, 'expire': 1626521912} 緩存過時後的結果: work 3s {'result': 1, 'expire': 1626521916} work 3s {'result': 2, 'expire': 1626521916}
弱引用參考:
https://blog.51cto.com/sleepd/1073044
https://blog.csdn.net/z_feng12489/article/details/89433878
本地緩存參考:
https://blog.csdn.net/weixin_34240520/article/details/92022464
functiontools.wraps的做用:
https://www.cnblogs.com/liuwei0824/p/10405212.htmlhtml