1. ホーム
  2. python

[解決済み] 関数デコレータを作成し、それらを連鎖させるには?

2022-02-04 23:54:24

質問

Pythonで以下のような2つのデコレータを作るにはどうしたらよいでしょうか。

@makebold
@makeitalic
def say():
   return "Hello"

...が返ってくるはずです。

"<b><i>Hello</i></b>"

を作ろうとしているわけではありません。 HTML デコレータとデコレータチェイニングがどのように機能するかを理解しようとしているだけです。

どのように解決するのか?

チェックアウト ドキュメント で、デコレータがどのように動作するかを確認します。以下は、ご質問の内容です。

from functools import wraps

def makebold(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        return "<b>" + fn(*args, **kwargs) + "</b>"
    return wrapper

def makeitalic(fn):
    @wraps(fn)
    def wrapper(*args, **kwargs):
        return "<i>" + fn(*args, **kwargs) + "</i>"
    return wrapper

@makebold
@makeitalic
def hello():
    return "hello world"

@makebold
@makeitalic
def log(s):
    return s

print hello()        # returns "<b><i>hello world</i></b>"
print hello.__name__ # with functools.wraps() this returns "hello"
print log('hello')   # returns "<b><i>hello</i></b>"