def make_bold(fn):
return lambda : "<b>" + fn() + "</b>"
def make_italic(fn):
return lambda : "<i>" + fn() + "</i>"
@make_bold
@make_italic
def hello():
return "hello world"
helloHTML = hello()
出力:"<b><i>hello world</i></b>"
私はデコレータについて、またほとんどの例でデコレータがどのように機能するかについて大まかに理解しています。
この例では、 が 2 つあります。出力から、@make_italic
最初に が実行され、次に が実行されているようです@make_bold
。
これは、装飾された関数の場合、最初に関数を実行し、次に他のデコレータの先頭に向かって移動することを意味しますか?逆ではなく、@make_italic
first then のように。@make_bold
つまり、これはほとんどのプログラミング言語におけるトップダウンアプローチの標準とは異なるということですか? これはデコレータの場合だけですか? それとも私が間違っていますか?
ベストアンサー1
デコレーター包むデコレートする関数。つまり、関数をデコレートしたデコレータmake_bold
の結果をデコレートするのです。make_italic
hello
構文@decorator
は実際には単なる構文糖であり、次のようになります。
@decorator
def decorated_function():
# ...
実際には次のように実行されます:
def decorated_function():
# ...
decorated_function = decorator(decorated_function)
元のオブジェクトを返されたdecorated_function
オブジェクトに置き換えますdecorator()
。
デコレータを積み重ねると、そのプロセスが繰り返されます外向き。
それであなたのサンプルは次のようになります:
@make_bold
@make_italic
def hello():
return "hello world"
次のように拡張できます。
def hello():
return "hello world"
hello = make_bold(make_italic(hello))
ここでを呼び出すと、実際にはhello()
によって返されたオブジェクトを呼び出しています。は、ラップされた関数を呼び出すを返しました。これは の戻り値であり、これも元の を呼び出すラムダです。これらすべての呼び出しを展開すると、次のようになります。make_bold()
make_bold()
lambda
make_bold
make_italic()
hello()
hello() = lambda : "<b>" + fn() + "</b>" # where fn() ->
lambda : "<i>" + fn() + "</i>" # where fn() ->
return "hello world"
出力は次のようになります。
"<b>" + ("<i>" + ("hello world") + "</i>") + "</b>"