Decorator execution order

后端 未结 1 1488
失恋的感觉
失恋的感觉 2020-11-27 02:51
def make_bold(fn):
    return lambda : \"\" + fn() + \"\"

def make_italic(fn):
    return lambda : \"\" + fn() + \"\"

@make_b         


        
1条回答
  •  臣服心动
    2020-11-27 03:29

    Decorators wrap the function they are decorating. So make_bold decorated the result of the make_italic decorator, which decorated the hello function.

    The @decorator syntax is really just syntactic sugar; the following:

    @decorator
    def decorated_function():
        # ...
    

    is really executed as:

    def decorated_function():
        # ...
    decorated_function = decorator(decorated_function)
    

    replacing the original decorated_function object with whatever decorator() returned.

    Stacking decorators repeats that process outward.

    So your sample:

    @make_bold
    @make_italic
    def hello():
      return "hello world"
    

    can be expanded to:

    def hello():
      return "hello world"
    hello = make_bold(make_italic(hello))
    

    When you call hello() now, you are calling the object returned by make_bold(), really. make_bold() returned a lambda that calls the function make_bold wrapped, which is the return value of make_italic(), which is also a lambda that calls the original hello(). Expanding all these calls you get:

    hello() = lambda : "" + fn() + "" #  where fn() ->
        lambda : "" + fn() + "" # where fn() -> 
            return "hello world"
    

    so the output becomes:

    "" + ("" + ("hello world") + "") + ""
    

    0 讨论(0)
提交回复
热议问题