
独習Python [ 山田 祥寛 ]
こんにちは、monachan_papaです。
Pythonにはデコレータというかなり特殊な機能があります。名前から察するように、何かをデコレーションする機能です。
では、具体的にどんな機能か?そして、書き方は?じっくり見ていきましょう。
デコレータとは?
デコレータを一言で表すと、
この機能を使いこなせるようになると、例えば以下のようなシーンで威力を発揮することができます。
- 関数Aがある。
- これにログ機能を追加実装したくなった。
- しかし、関数Aのコードは絶対に変更したくない。
上記のシーン。欲張りな要件ですね。しかし、デコレータを使えば、実現可能です。
とはいえ、デコレータは構造上、複数の関数が絡み合って実現する機能になります。
よって、以降でスッテップ・バイ・ステップで説明していきます。
デコレータ作成の前提知識
デコレータを作る前提として、以下の文法をしっかりマスターしているのであれば、理解が早くなります。
もし、そもそも理解していない、あるいは理解があやふや。という御方は、これを機にマスターすることをおすすめします。
- 関数内関数
- 引数としての関数
- 戻り値としての関数
- *args
高階関数
関数を変数として扱う。
これを利用すると、「関数に追加処理をする関数」 ができます。
以下は、関数を変数として扱ったコード例です。
流れを正確につかめるように、かなり詳細にコメント付与してあります。
実行すると、
Python
デコレータ
マスターしよう!
と出力されます。
# 「追加処理が施された関数」の引数に、
# 「ベースとなる関数」を受け取る。
def add_fn(f):
# 「追加処理とベース処理がミックスされた関数」
def mix_fn():
print('Python')
f()
print('マスターしよう!')
# 「追加処理とベース処理がミックスされた関数」をリターン
return mix_fn
# 「ベースとなる関数」
def base_fn():
# 単なるprint出力だけ
print('デコレータ')
# 「追加処理が施された関数」の引数に、
# 「ベースとなる関数」を渡す。
# 戻り値は「追加処理とベース処理がミックスされた関数」となる。
# これを「デコレートされた関数」に格納する。
deco_fn = add_fn(base_fn)
# 「デコレートされた関数」を実行する。
deco_fn()
Python
デコレータ
マスターしよう!
上記のコードで、ポイントとなる点があるので、列挙します。
- base_fn()関数は、一切コード変更がされていない。
- 関数を変数として扱っているところは、関数名の後ろの括弧()なし。
- add_fn()関数のように、引数や戻り値に関数を含んでいるものを高階関数と呼ぶ。
これらを理解した上で、次に進みます。

独習Python [ 山田 祥寛 ]
高階関数を呼び出すデコレータ
基本形
add_dn()関数は高階関数であり、引数や戻り値に関数を含んでいました。
この高階関数をもっと簡単に呼び出す仕組みがあれば、とても楽です。
そうです。それを仕組み化し、関数に対し、常に指定した高階関数を呼び出すのがデコレータなのです。
構文はとても簡単で、デコレートされる関数定義の上に、@高階関数名を書くだけです。
def デコレートされる関数名():
# 処理
さきほどのコードを、デコレータを使って書き換えてみます。
def add_fn(f):
def mix_fn():
print('Python')
f()
print('マスターしよう!')
return mix_fn
@add_fn
def base_fn():
print('デコレータ')
base_fn()
Python
デコレータ
マスターしよう!
とてもシンプルになりましたね。これはかなりの省力化です。
しかし、コードの流れが初心者には追いづらくなってします、というデメリットがあります。
デコレートされる関数に引数や戻り値がある場合
さきほどのコードでは、デコレートされる関数base_fn()には引数がありませんでした。また、戻り値もありませんでした。
もし、デコレートされる関数に引数や戻り値があった場合は、あのコードのままだと使えません。
しかし、可変長引数と戻り値の設定をすることにより、デコレータが使えるようになります。
以下は、デコレートされる関数に引数や戻り値がある場合の対応方法です。
def add_fn(f):
def mix_fn(*args):
print('Python')
print('マスターしよう!')
res = f(*args)
return res
return mix_fn
@add_fn
def base_fn(a, b):
return a + b
res = base_fn('デコレータ', 'も、そろそろね。')
print(res)
Python
マスターしよう!
デコレータも、そろそろね。
以上で、デコレータについての説明を終わります。
デコレータは知らなくても、何とかなる機能ではあります。特に初心者のうちは、学習効率という観点から初めはスルーで良いと考えます。なぜなら、他にもっと優先してマスターしなければならない内容があるからです。
しかし、いつかはマスターしたいですよね。Python使いならば。
また、冒頭でも述べたように、デコレータは前提知識自体が重要で価値あるものなので、学習すると本当にためになりますよ。
独習Python [ 山田 祥寛 ]では、デコレータの構造を詳細な図入りで、さらに詳しく丁寧に解説しています。「関数内関数、引数としての関数、戻り値としての関数、*args」についてもきっちり解説されているので、大変おすすめです。

独習Python [ 山田 祥寛 ]
また、爆速で デコレータを含めPython文法 を学びたい御方にはプログラミングスクールを考えるのも、ひとつの手です。独学よりも効果が出やすいですが、いかんせん投資がけっこうかかります。しかし、techgymというスクールは通うか通わないかは別として、無料のサンプルテキスト&解説動画がもらえます。これをとりあえず getしてまずは試しに体験学習するのもありでしょう。

コメント