Pythonの回顧デコレータ


前の記事でPython decorator series , 我々は、デコレータ、どのように動作し、シンプルな機能ベースのデコレータとクラスベースのデコレータとパラメータをサポートするデコレータを実装するために、デコレータを学んだ.この記事では、結果をキャッシュする簡単なmemoizationデコレータ関数を作成します.
回想は、高価な関数呼び出しの結果を格納し、同じ入力が再び発生するときにキャッシュされた結果を返すことによってプログラムを高速化するために使用される最適化手法です.

数の階乗


再帰的に数の階乗を計算する関数を作りましょう.

def factorial(n):
    if n == 1:
        return n
    else:
        return n * factorial(n - 1)


if __name__ == '__main__':
    print(factorial(20))
    print(factorial(10))
    print(factorial(15))
    print(factorial(5))

出力
2432902008176640000
3628800
1307674368000
120
与えられた数の階乗が常に同じであるので、与えられた値の結果をキャッシュすることによって、この機能を最適化することができます.デコレータ機能を作りましょう.
from functools import wraps


def memoize(func):
    cache = {}

    @wraps(func)
    def wrapper(*args, **kwargs):
        if args not in cache:
            print(f"Calling for {func.__name__}({args})")
            cache[args] = func(*args, **kwargs)
        else:
            print(f"Using cached result for {func.__name__}({args})")
        return cache[args]

    return wrapper


@memoize
def factorial(n):
    if n == 1:
        return n
    else:
        return n * factorial(n - 1)


if __name__ == '__main__':
    print(factorial(20))
    print(factorial(10))
    print(factorial(15))
    print(factorial(5))

出力
Calling for factorial((20,))
Calling for factorial((19,))
Calling for factorial((18,))
Calling for factorial((17,))
Calling for factorial((16,))
Calling for factorial((15,))
Calling for factorial((14,))
Calling for factorial((13,))
Calling for factorial((12,))
Calling for factorial((11,))
Calling for factorial((10,))
Calling for factorial((9,))
Calling for factorial((8,))
Calling for factorial((7,))
Calling for factorial((6,))
Calling for factorial((5,))
Calling for factorial((4,))
Calling for factorial((3,))
Calling for factorial((2,))
Calling for factorial((1,))
2432902008176640000
Using cached result for factorial((10,))
3628800
Using cached result for factorial((15,))
1307674368000
Using cached result for factorial((5,))
120
出力から,10,15,5の因子を計算するためにキャッシュ結果を使用した.
次の記事では、様々な種類のデコレータのレシピを実装します.今後の記事をお楽しみください.ニュースレターを購読し、私の将来の記事を得るために私と接続します.