當前位置: 首頁>>代碼示例 >>用法及示例精選 >>正文


Python functools.lru_cache用法及代碼示例


用法:

@functools.lru_cache(user_function)
@functools.lru_cache(maxsize=128, typed=False)

裝飾器使用可保存到 maxsize 最近調用的 memory 可調用對象來包裝函數。當使用相同的參數定期調用昂貴的或 I/O 綁定的函數時,它可以節省時間。

由於字典用於緩存結果,因此函數的位置和關鍵字參數必須是可散列的。

不同的參數模式可以被認為是具有不同緩存條目的不同調用。例如,f(a=1, b=2)f(b=2, a=1) 的關鍵字參數順序不同,並且可能有兩個單獨的緩存條目。

如果指定了user_function,它必須是可調用的。這允許 lru_cache 裝飾器直接應用於用戶函數,而將 maxsize 保留為其默認值 128:

@lru_cache
def count_vowels(sentence):
    return sum(sentence.count(vowel) for vowel in 'AEIOUaeiou')

如果 maxsize 設置為 None ,則禁用 LRU 函數,並且緩存可以無限製地增長。

如果typed設置為true,不同類型的函數參數將分別緩存。如果typed 為假,實現通常會將它們視為等效調用並僅緩存單個結果。 (某些類型,例如strint,即使typed 為假,也可能被單獨緩存。)

請注意,類型特異性僅適用於函數的直接參數,而不適用於它們的內容。標量參數 Decimal(42)Fraction(42) 被視為具有不同結果的不同調用。相反,元組參數('answer', Decimal(42))('answer', Fraction(42)) 被視為等效。

包裝的函數使用 cache_parameters() 函數進行檢測,該函數返回一個新的 dict ,顯示 maxsizetyped 的值。這僅供參考。改變值沒有效果。

為了幫助測量緩存的有效性並調整 maxsize 參數,包裝函數使用 cache_info() 函數進行檢測,該函數返回顯示 hits , misses , maxsizecurrsize 的命名元組。

裝飾器還提供了一個cache_clear() 函數用於清除或使緩存無效。

原始底層函數可通過__wrapped__ 屬性訪問。這對於自省、繞過緩存或使用不同的緩存重新包裝函數很有用。

緩存保留對參數和返回值的引用,直到它們超出緩存或緩存被清除。

當最近的調用是即將到來的調用的最佳預測指標時,LRU (least recently used) cache 效果最好(例如,新聞服務器上最受歡迎的文章往往每天都在變化)。緩存的大小限製確保緩存不會不受限製地增長 long-running 進程,例如 Web 服務器。

一般來說,LRU 緩存應該隻在你想重用之前計算的值時使用。因此,使用side-effects 緩存函數、需要在每次調用時創建不同的可變對象的函數或諸如time() 或random() 之類的不純函數是沒有意義的。

靜態 Web 內容的 LRU 緩存示例:

@lru_cache(maxsize=32)
def get_pep(num):
    'Retrieve text of a Python Enhancement Proposal'
    resource = 'https://www.python.org/dev/peps/pep-%04d/' % num
    try:
        with urllib.request.urlopen(resource) as s:
            return s.read()
    except urllib.error.HTTPError:
        return 'Not Found'

>>> for n in 8, 290, 308, 320, 8, 218, 320, 279, 289, 320, 9991:
...     pep = get_pep(n)
...     print(n, len(pep))

>>> get_pep.cache_info()
CacheInfo(hits=3, misses=8, maxsize=32, currsize=8)

使用緩存高效計算 Fibonacci numbers 以實現 dynamic programming 技術的示例:

@lru_cache(maxsize=None)
def fib(n):
    if n < 2:
        return n
    return fib(n-1) + fib(n-2)

>>> [fib(n) for n in range(16)]
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377, 610]

>>> fib.cache_info()
CacheInfo(hits=28, misses=16, maxsize=None, currsize=16)

3.2 版中的新函數。

在 3.3 版中更改:添加了typed選項。

在 3.8 版中更改:添加了user_function選項。

3.9 版中的新函數:增加了函數cache_parameters()

相關用法


注:本文由純淨天空篩選整理自python.org大神的英文原創作品 functools.lru_cache。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。