スターエンジニアになりたい

異世界転生を待って早10年

Pythonのデコレーターでメタプログラミング 【第1回】【動的に装飾】 #5

どうも hkrblog です.

昨日までの投稿内容がクソ雑魚wすぎたのか、あまりビューがないので
少しは誰かの役に立ちそうなPythonのデコレーターに関する記事を今日から3回に渡って書いていこうと思います.

デコレーターというと、メソッドに処理を加えるようなイメージがあると思います.
実際その解釈でOKだと思うんですが、
今シリーズの内容を超ざっくりいうと、メタプログラミングのような使い方もできます という記事です.

ただ、急に入ると変に難しく感じたりするので、第一回ではデコレーターのド基本の使い方を見ていこうと思います.
デコレーターなんて知ってるわ!!!!コラ!!!みたいな人はまずこの記事を見ないとは思うのですが、
第一回の対象読者ではないのでブラウザをそっと閉じてください...w
まずコードです.


def deco(func):
    def inner():
        print('before func')
        ret = func()
        print(ret + '!!!')
        print('after func')
    return inner


def sample():
    return 'Hello'


def main():
    # Original sample output
    print(sample())
    print('--------------')

    # Decorated sample output
    decorated = deco(sample)
    decorated()


if __name__ == '__main__':
    main()

仕事でpython使わなくなって久しいので、
デコレーターって実際どう書くんだったっけ?ってなって一旦これで思い出しましたw
危ない危ないw

まずmain()から見ていきます.
print(sample())sampleを呼び出し、出力してますね.
sample()はというとreturn 'Hello'するだけという簡単なメソッドです.

次が本題です.
doco(sample)sampleの関数オブジェクトを引数に、関数deco()を呼び出しました.
decoはというと、innerを返してます.(一旦funcは忘れて...)
innerは何かというと、内部関数innerの関数オブジェクトです.
で、その関数オブジェクトを変数decoratedにぶち込みます.
innerの関数オブジェクトなので、decorated()でinner()が呼ばれますね.
これでやっとsample()に話が戻ってきて、sampleはfuncなので、ret = func()ここで実行されました.

出力結果がこちらです.

Hello
--------------
before func
Hello!!!
after func

どうでしょうか、わかりましたでしょうか....?
ではまた次回#6、第2回 デコレーターでメソッドの中身を生やすでお会いしましょう.
さよなら~~~.