把函式結果快取一段時間,比如讀取乙個mongodb,mongodb中的內容又在發生變化,如果從部署後,自始至終只去讀一次那就感觸不到變化了,如果每次呼叫乙個函式就去讀取那太頻繁了耽誤響應時間也加大了cpu負擔,也不行。那就把結果快取一段時間。
來乙個快取一段時間的裝飾器。
classfunctionresultcacher:
logger = logmanager('
functionresultchche
').get_logger_and_add_handlers()
func_result_dict ={}
"""
"""@classmethod
defcached_function_result_for_a_time(cls, cache_time):
"""函式的結果快取一段時間裝飾器
:param cache_time 快取的時間
:type cache_time : float
"""def
_cached_function_result_for_a_time(fun):
@wraps(fun)
def__cached_function_result_for_a_time(*args, **kwargs):
if len(cls.func_result_dict) > 1024:
cls.func_result_dict.clear()
key =cls._make_arguments_to_key(args, kwargs)
if (fun, key) in cls.func_result_dict and time.time() - cls.func_result_dict[(fun, key)][1] return
cls.func_result_dict[(fun, key)][0]
else
: result = fun(*args, **kwargs)
cls.func_result_dict[(fun, key)] =(result, time.time())
cls.logger.debug(
'函式 [{}] 此次不使用快取
'.format(fun.__name__
))
return
result
return
__cached_function_result_for_a_time
return
_cached_function_result_for_a_time
@staticmethod
def_make_arguments_to_key(args, kwds):
key =args
ifkwds:
sorted_items =sorted(kwds.items())
for item in
sorted_items:
key +=item
return key
測試下:
@functionresultcacher.cached_function_result_for_a_time(3)可以發現只計算了兩次,第一次是開始時候沒有快取所以要計算,第二次有快取了就不計算,第三次因為超過了3秒就不使用快取了,所以要計算。def f10(a, b, c=3, d=4):
print('計算中。。。')
return a + b + c + d
print(f10(1, 2, 3, 4))
print(f10(1, 2, 3, 4))
time.sleep(4)
print(f10(1, 2, 3, 4))
執行結果是這樣
需要注意一點的是用字典做的快取,如果函式的結果非常大,部署後一直執行,一段時間後會佔一大塊記憶體,所以設定了1024個快取結果,否則就清除字典。如果函式沒有入參或者入參都是一樣的那就沒事,如果入參不一樣且函式返回結果超長是乙個幾百萬長度的字串,那就用此裝飾器時候要小心點。
把if len(cls.func_result_dict) > 1024: 改為if sys.getsizeof(cls.func_result_dict) > 100 * 1000 * 1000,則是直接判斷記憶體。
此裝飾器可以裝飾在函式上,當然也可以裝飾在方法上了。因為 *args **kwargs代表了所有引數,self只是其中的乙個特殊引數而已,所以可以裝飾在方法上。
functools模組有個lru_cache裝飾器,是快取指定次數的裝飾器,這個是快取指定時間的。
Windows系統下獲取一段函式執行的時間
如果要獲取精確到毫秒的函式執行時間,在windows pc下可以使用queryperformancecounter介面 大致用法如下 include windows.h large integer freq,start,end double dtime 0 queryperformancefrequ...
多型 結合一段程式,輸出結果,注意分析
解析,這裡為了方便看,我就把三個類放到了一起寫,我結合題目給大家做乙個圖形分析 這個題目是比較難的,注意看圖 從main方法裡面開始在棧空間裡面new了兩個變數a,b a 是指向堆裡面的 new a b指向堆裡面的new b 注意,因為a是b的父類,子類在new 物件的時候會先new 乙個父類的物件...
被疏忽的一段Python語法
python提供了有序 sequence 型別 字串,元組,列表都是有序型別 並且提供了特殊的語法來方便對這些型別進行操作,最常用的有切片操作。同一有序型別的物件之間支援 操作符,用來連成乙個新的有序物件,有序物件也可以與乙個整數進行相乘,得到乙個新的有序物件。在除錯的時候,我經常使用這樣的語句來列...