es un decorador en Python exactamente el mismo que llamar a una función en una función?

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

Pregunta

pensé que haciendo

@f
def g():
   print 'hello'

es exactamente el mismo que

def g():
   print 'hello'
g=f(g)

Sin embargo, tuve este código, que los usos contextlib.contextmanager:

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

que funciona y los rendimientos 1 3 2

Y cuando traté de cambiarlo a

def f():
    print 1
    yield
    print 2
f=contextlib.contextmanager(f)
with f:
    print 3

consigo AttributeError: 'function' object has no attribute '__exit__'

¿Qué me falta? ¿hay algo de magia negro específicamente en contextlib.contextmanager, o me entiende mal cómo trabajan los decoradores en general?

¿Fue útil?

Solución

Sí, decorador es exactamente lo mismo que llamar a una función y asignando al valor devuelto

En este caso, el error viene porque usted no está llamando a la función, código de manera correcta sería

def f():
    print 1
    yield
    print 2

f=contextlib.contextmanager(f)
with f():
    print 3

También no estoy seguro de si la prueba de código, ya que el código decorador has dado fallará debido a la misma razón

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

Error:

    with f:
AttributeError: 'function' object has no attribute '__exit__'
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top