先日、C# でメソッドのメモ化に挑戦しました。
ラムダ式を使って、出来るだけメソッドの定義に近い形にしています。それでも漂う無理やり感。完全に消すことは無理だった……。
話は変わって、Python にはデコレータという構文があります。デコレータを使えば、C# で無理やり行ったメモ化を、スマートに記述できます。百聞は一見にしかず。
# 関数をメモ化する関数 def memoization(method): cache = {} def memo(name): try: return cache[name] except: cache[name] = method(name) return cache[name] return memo # C# の属性みたいな記述で関数をメモ化できる @memoization def greet(name): return "Hello, " + name
ふつくしい・・・。
Python のデコレータは関数の「修飾」ではなく「差し替え」だと解釈しています。上記サンプルだと、「greet メソッドを memoization の戻り値に差し替える」みたいな感じ。私の場合は、そう考えた方が分かりやすかった。
例えば、次のサンプル。
def morning(method): def memo(name): return "Good morning." return memo @morning def greet(name): return "Hello, " + name print(greet("Ihicro")) #=> Good morning. print(greet("Hideki")) #=> Good morning. print(greet("Ichiro")) #=> Good morning.
これを実行すると、"Good morning." が3回出力されます。"Hello" なんて全く出力されません。greet 関数が行う処理が、morning 関数で返したクロージャが行う処理に差し替わっています。