Pythonのいろんなコードを見ていると唐突に
「@decorator」
みたいな関数の上に “@(アットマーク)” をつけて単語名が書いてあるコードを目にすることがあると思います。
これがなんていうのかわかんないし、調べてみてもなんだかよくわからなかったということが多くあると思います。
今回はそんな人のためにこのアットマークがつく処理は何なのか、どういう処理をするのか、メリットは何なのかっていうのを初心者向けに書いていこうと思います。
デコレータとは
関数の上に@マークがついている単語の意味は「デコレータ」といいます。
デコレータとはある関数の処理の前後に別の処理を付け加えるための機能です。
decorator(デコレータ)は日本語で修飾する者という意味ですので、関数をを別の関数で飾りつけるというイメージからこの名前が使われているのだと推察できます。
では、関数に対して別の関数を付け加えるというのはどういったイメージになるのか分かりやすく解説します。
例えば、絵を描くという関数を作ったとします。
その関数は絵を描いてくれはするものの、色を塗ったり、影をつけたりといったことはしてくれません。
そこで、色を塗ったり影をつけたりする関数を別に作ったとします。

この色を塗る関数を絵を描く関数に対してデコレータとして記述することで、絵を描く関数を呼び出すだけで絵を描くところから色付け、影つけまでやってくれるようになるわけです。

これがデコレータというわけです。
デコレータとして呼び出すことで、本来何か所にも記載しなければならない処理を一行付け加えるだけでその処理を実施してくれるので、その処理を書く手間と、コードの可読性、さらには修正する際にはデコレータさえ直せばいいのでメンテナンス性も上がります。
デコレータの使い方
デコレータを使うにはまず、デコレータ用の関数を作成する必要があります。
デコレータの関数は少し特殊な構造をしております。

デコレータ関数は基本的に上記のような構造をしております。
これだけだとわかりにくいと思いますのでそれぞれの要素について詳しく見ていきましょう。
デコレータ用の関数は以下のように引数にデコレートしたい関数を指定します。
その中にさらに追加処理を記述するための関数を記載します。
これは呼び出した関数の処理を包含するための関数になるので [wrapper] という名前にする場合が殆どです。
また、wrapper 関数の引数には何でも受け取れるようにするために、任意引数の *args と **keywords を指定します。
[*args] は任意の数が指定可能の位置引数で、 [**keywords] は任意の数が指定可能のキーワード引数です。
この wrapper 関数の中に付け加えたい処理と、付け加える関数を呼び出す処理を記載します。
付け加える関数を呼び出す前に処理を書けば先にwrapper関数の内容が実行され後に書いた処理はつけ加えた関数を呼び出した後に実行されます。
上記のように構成することでデコレータ関数として役割を実行することができます。
-サンプルコード
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
#デコレータとして利用する関数 def aisatu(fnc): """ fnc : デコレートされる関数 """ # デコレートする関数を装飾するための関数 def wrapper(*args, **keywords): """ *args : 任意の位置引数 **keywords : 任意のキーワード引数 """ # 前処理 # 挨拶処理 print('お世話になっております。') print('○○システムのカズと申します。') print('') # デコレート対象の関数の実行 v = fnc(*args, **keywords) # 後処理 # 署名 print('') print('■■■■■■■■■■■■') print('カズーリ アンジェロ') print('東京都○○区○○1-1-1') print('test@test_company.com') print('■■■■■■■■■■■■') return v return _wrapper #関数のデコレート @aisatu def mail(): print("○○案件の資料を作成いたしましたのでご確認いただけますようお願いいたします。") print("よろしくお願いいたします。") mail() #関数の実行 |
上記のコードはメールとかで最初の決まりのあいさつと最後の署名を自動でつけてくれる関数をデコレート関数として定義し、本文を別の関数に記すことで本文を記載した関数だけ呼び出せば、最初の挨拶と署名をつけた状態で本文が出力されるという仕組みになっています。
デコレータの利点
ではなぜこのような関数を用意するのか疑問に感じる方へイメージが付きやすいようにお話しします。
例えば、朝起きて朝ごはんを作って朝食を食べ、出社して働いて、帰ってきたらご飯を作ってお風呂に入って寝るという一日の決まった流れがあったとします。

上記のような流れで毎日過ごしていた場合、仕事は日々変わるし自分にしか対応できないものでしょうから人には任せられなさそうですが、ご飯を作ったり風呂を洗ったりというのであれば(オレンジの項目)他人にお願いしてもできそうですよね?
こういう処理を実施する度に毎回やらなきゃいけない決まった汎用的な仕事を、別のプログラムに任せて実施してもらう、つまりそのプログラムがデコレータというわけです。
上記の例でいえばこういう家事のような仕事はメイドさんや家政婦さんに行ってもらうというのがイメージしやすいと思いますが、メイドさんがここでいうデコレータになるというわけです。

なのでデコレータを自作する際には実装したいプログラムの流れをイメージして、他のプログラムでも使えるような汎用的な処理がある場合はそのデコレータを実装すると良いと思います。
いかがでしょうか。
デコレータは使わなくてもやりたい処理は実装できるのですが、扱えるようになるとプログラムが簡潔になるだけでなく実装にかかる時間も短縮できるようになるので、扱える場面があったら積極的に使うようになるとプログラミングも捗ると思います。
今回はここまでです。
お疲れ様でした。
コメント