es un decorador en Python exactamente el mismo que llamar a una función en una función?
-
28-09-2019 - |
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?
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__'