Los decoradores de Python se ejecutan antes de que se llame a la función que está decorando.

StackOverflow https://stackoverflow.com/questions/341379

  •  19-08-2019
  •  | 
  •  

Pregunta

Como ejemplo,

def get_booking(f=None):
    print "Calling get_booking Decorator"
    def wrapper(request, **kwargs):
        booking = _get_booking_from_session(request)
        if booking == None:
            # we don't have a booking in our session.
            return HttpRedirect('/')
        else:
            return f(request=request, booking=booking, **kwargs)
    return wrapper

@get_booking
def do_stuff(request, booking):
    # do stuff here

El problema que tengo es que se llama al decorador @get_booking incluso antes de llamar a la función que estoy decorando.

Salida al inicio:

Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
Calling get_booking Decorator
[26/Oct/2008 19:54:04] "GET /onlinebooking/?id=1,2 HTTP/1.1" 302 0
[26/Oct/2008 19:54:05] "GET /onlinebooking/ HTTP/1.1" 200 2300
[26/Oct/2008 19:54:05] "GET /site-media/css/style.css HTTP/1.1" 200 800
[26/Oct/2008 19:54:05] "GET /site-media/css/jquery-ui-themeroller.css HTTP/1.1" 200 25492

Ni siquiera he llamado a una función que está decorada en este momento.

Recién estoy comenzando con los decoradores, así que quizás me estoy perdiendo algo. ¿Alguna ayuda?

¿Fue útil?

Solución

Creo que los decoradores de pitón son solo azúcar sintáctico.

@foo
def bar ():
    pass

es lo mismo que

def bar ():
    pass
bar = foo(bar)

Como puede ver, se está llamando a foo aunque no se haya llamado a bar . Es por eso que ve la salida de su función decoradora. Su salida debe contener una sola línea para cada función a la que aplicó su decorador.

Otros consejos

Dado que está comenzando con los decoradores, creo que leerlos será útil, para que conozca las trampas y las soluciones alternativas de antemano.

Aquí hay dos enlaces a discusiones anteriores sobre decoradores.

El decorador de Python hace olvidar la función que pertenece a una clase ¿Qué hace functools.wraps?

Además, el segundo enlace menciona 'functools', un módulo para funciones de orden superior, que actúan o devuelven otras funciones. Se recomienda el uso de functools.wraps ya que conserva la cadena de documentos de la función original (decorada).

Otro problema fueron las firmas de métodos incorrectas al generar documentos automáticos para mi proyecto. pero hay una solución alternativa: Conservación de firmas de funciones decoradas

Espero que esto ayude.

Se llama a un decorador tan pronto como se define la función decorada. Es equivalente a escribir algo como esto:

def __do_stuff(...):
    ...

do_stuff = get_booking(__do_stuff)

los decoradores de python son funciones aplicadas a una función para transformarla:

@my_decorator
def function (): ...

es como hacer esto:

def function():...
function = my_decorator(function)

Lo que quieres hacer es:

def get_booking(f=None):
    def wrapper(request, **kwargs):
        print "Calling get_booking Decorator"
        booking = _get_booking_from_session(request)
        if booking == None:
            # we don't have a booking in our session.
            return HttpRedirect('/')
        else:
            return f(request=request, booking=booking, **kwargs)
    return wrapper
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top