Python デコレータを学ぶ 3

デコレータで引数を取るのではなく、デコレートされる関数の方で引数を取って、それをデコレータ側でも使用する場合については以下のようになるようです。

# デコレータ
def how_are_you(func):
    def wrapper(arg1, arg2):
        print('I got args! Look:', arg1, arg2)
        func(arg1, arg2)
        print('how are you,', arg1, '?')
    return wrapper


# デコレートされる関数
@how_are_you
def greeting(first_name, last_name):
    print('hello,', first_name, last_name)

# 実行する
greeting('Jude', 'Law')

実行した結果はこうなります。

$ python decolate.py

I got args! Look: Jude Law
hello, Jude Law
how are you, Jude ?

デフォルト値は wrapper に渡せない?

ただ、引数にデフォルト値を設定していた場合、それらはデコレータ側では使えないようでした。 まずデコレータを使わない普通の関数定義の場合です。

# それぞれデフォルト値を設定
def greeting(first_name='Takashi', last_name='Yamada'):
    print('hello,', first_name, last_name)

# 実行する
greeting()
$ python decolate.py

hello, Takashi Yamada

デフォルト値として設定した値が使われていることがわかります。 次に同じ関数に対して先ほどのデコレータを適用してみます。

def how_are_you(func):
    def wrapper(arg1, arg2):
        print('I got args! Look:', arg1, arg2)
        func(arg1, arg2)
        print('how are you,', arg1, '?')
    return wrapper

@how_are_you
def greeting(first_name='Takashi', last_name='Yamada'):
    print('hello,', first_name, last_name)

# 実行する
greeting()
$ python decolate.py

Traceback (most recent call last):
  File "decolate.py", line 77, in <module>
    greeting()
TypeError: wrapper() missing 2 required positional arguments: 'arg1' and 'arg2'

エラーになっていました。