【Python】Python ~ デコレータ @xxxx ~

■ はじめに

https://dk521123.hatenablog.com/entry/2020/05/20/195621

で、デコレータについて触れた。
Python のコードの幅が広がりそうなので、メモっておく。

目次

【1】デコレータ
 1)使いどころ
【2】Python標準のデコレータ
【3】サンプル
 例1:Hello world
【4】デコレータあれこれ
 1)元の関数のメタデータを維持するには...

【1】デコレータ

* デコレータ(Decorator) = 修飾する
* 既存の関数を直接変更せずに、その関数に機能を追加したり変更したりすることができる
 ⇒ デザインパターンのDecorator パターンと同じっぽい
* Javaでいうと「Override」みたいな感じで、関数を上書きする

デザインパターン】【Java】Decorator パターン ~装飾者~
https://dk521123.hatenablog.com/entry/2014/02/16/000100

1)使いどころ

* 関数を実行する前後に処理を加えたい場合
 => ログを入れたいなど

【2】Python標準のデコレータ

以下のデコレータは、クラスで使用する。

@classmethod
@staticmethod
@property

Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537

【3】サンプル

例1:Hello world

def demo_decorator(func):
  def inner_func(*args, **kwargs):
    print("前処理")
    func(*args, **kwargs) # ここでデコレータ付与したメソッドを呼び出し
    print("後処理")
  return inner_func

@demo_decorator
def say_hello(name):
  print("Hello, {}!".format(name))

say_hello("Mike")

出力結果

前処理
Hello, Mike
後処理

【4】デコレータあれこれ

1)元の関数のメタデータを維持するには...

from functools import wraps

def demo_decorator(func):
  @wraps(func) # ここに注目
  def inner_func(*args, **kwargs):
    print("前処理")
    func(*args, **kwargs)
    print("後処理")
  return inner_func

@demo_decorator
def say_hello(name):
  print("Hello, {}!".format(name))

say_hello("Mike")
print(say_hello.__name__)

出力結果

前処理
Hello, Mike!
後処理
say_hello

参考文献

https://techacademy.jp/magazine/33806
https://qiita.com/tmatoba/items/d257519b018b8cd0cc2e
https://note.crohaco.net/2014/python-decorator/
https://techblog.recochoku.jp/2407
https://www.sejuku.net/blog/25130

関連記事

Python ~ 基本編 / 文字列 ~
https://dk521123.hatenablog.com/entry/2019/10/12/075251
Python ~ 基本編 / クラス・継承 ~
https://dk521123.hatenablog.com/entry/2019/08/29/220537
Python ~ 可変長引数 / *args kwargs ~
https://dk521123.hatenablog.com/entry/2023/11/01/000915
デザインパターン】【Java】Decorator パターン ~装飾者~ **
https://dk521123.hatenablog.com/entry/2014/02/16/000100