Python のデコレータがうらやましい

先日、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 関数で返したクロージャが行う処理に差し替わっています。

デコレータ気に入った。C# にも欲しい。Python ウラマヤシス(´・ω・`)