Orden de ejecución del decorador

def make_bold(fn): return lambda : "" + fn() + "" def make_italic(fn): return lambda : "" + fn() + "" @make_bold @make_italic def hello(): return "hello world" helloHTML = hello() 

Salida: "hello world"

Apenas entiendo sobre decoradores y cómo funciona con uno de ellos en la mayoría de los ejemplos.

En este ejemplo, hay 2 de él. Desde la salida, parece que @make_italic ejecuta primero, luego @make_bold .

¿Esto significa que para las funciones decoradas, primero ejecutará la función primero y luego se moverá hacia la parte superior para otros decoradores? Al igual que @make_italic primero y luego @make_bold , en lugar de lo contrario.

Entonces, ¿esto significa que es diferente de la norma del enfoque de arriba hacia abajo en la mayoría de los lenguajes de progtwigción? ¿Solo para este caso de decorador? ¿O me equivoco?

Los decoradores envuelven la función que están decorando. Así que make_bold decoró el resultado del decorador make_italic , que decoró la función de hello .

La syntax de @decorator es en realidad solo azúcar sintáctica; el seguimiento:

 @decorator def decorated_function(): # ... 

Se ejecuta realmente como:

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

reemplazando el objeto decorated_function original con cualquier decorator() devuelto.

Astackndo decoradores repite ese proceso hacia el exterior .

Así que su muestra:

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

se puede ampliar a:

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

Cuando llamas a hello() ahora, estás llamando al objeto devuelto por make_bold() , realmente. make_bold() devolvió un lambda que llama a la función make_bold , que es el valor de retorno de make_italic() , que también es un lambda que llama al original hello() . Expandiendo todas estas llamadas obtienes:

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

por lo que la salida se convierte en:

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