一段非常簡單代碼
普通調用方式
def console1(a, b): print("進入函數") return (a, b) print(console1(3, 'a')) print(console1(2, 'b')) print(console1(3.0, 'a'))
很簡單的一段代碼,傳入兩個參數。然后打印輸出。
輸出結果
進入函數 (3, 'a') 進入函數 (2, 'b') 進入函數 (3.0, 'a')
使用某個裝飾器后
接下來我們引入functools模塊的lru_cache,python3自帶模塊。
from functools import lru_cache @lru_cache() def console2(a, b): print("進入函數") return (a, b) print(console2(3, 'a')) print(console2(2, 'b')) print(console2(3.0, 'a'))
進入函數 (3, 'a') 進入函數 (2, 'b') (3, 'a')
我們發現,少了一次進入函數的打印,這是怎么回事呢?
這就是接下來要說的LRU緩存技術了。
我們理解下什么是LRU
LRU (Least Recently Used) 是緩存置換策略中的一種常用的算法。當緩存隊列已滿時,新的元素加入隊列時,需要從現有隊列中移除一個元素,LRU 策略就是將最近最少被訪問的元素移除,從而騰出空間給新的元素。
python中的實現
python3中的functools模塊的lru_cache實現了這個功能,
lru_cache裝飾器會記錄以往函數運行的結果,實現了備忘
(memoization)功能,避免參數重復時反復調用,達到提高性能的作用,在遞歸函數中作用特別明顯。這是一項優化技術,它把耗時的函數的結果保存起來,避免傳入相同的參數時重復計算。
帶參數的lru_cache
使用方法lru_cache(maxsize=128, typed=False)
maxsize可以緩存最多個此函數的調用結果,從而提高程序執行的效率,特別適合於耗時的函數。
參數maxsize為最多緩存的次數,如果為None,則無限制,設置為2的n次冪時,性能最佳;
如果 typed=True,則不同參數類型的調用將分別緩存,例如 f(3) 和 f(3.0),默認False
來一段綜合代碼:
from functools import lru_cache def console1(a, b): print("進入函數") return (a, b) @lru_cache() def console2(a, b): print("進入函數") return (a, b) @lru_cache(maxsize=256, typed=True) def console3(a, b): ''' :param a: :param b: :return: ''' print("進入函數") return (a, b) print(console1(3, 'a')) print(console1(2, 'b')) print(console1(3.0, 'a')) print("*" * 40) print(console2(3, 'a')) print(console2(2, 'b')) print(console2(3.0, 'a')) print("*" * 40) print(console3(3, 'a')) print(console3(2, 'b')) print(console3(3.0, 'a'))
同樣的可以用到爬蟲的去重操作上,避免網頁的重復請求。
在后期存儲的時候做判斷即可。
from functools import lru_cache from requests_html import HTMLSession session=HTMLSession() @lru_cache() def get_html(url): req=session.get(url) print(url) return req urllist=["https://www.baidu.com","https://pypi.org/project/pylru/1.0.9/","https://www.baidu.com"] if __name__ == '__main__': for i in urllist: print(get_html(i))
輸出
https://www.baidu.com <Response [200]> https://pypi.org/project/pylru/1.0.9/ <Response [200]> <Response [200]>
鏈接:https://juejin.im/post/5bc5a255e51d450e64765065