è un decoratore in python esattamente lo stesso di chiamare una funzione su una funzione?
-
28-09-2019 - |
Domanda
ho pensato che facendo
@f
def g():
print 'hello'
è esattamente lo stesso di
def g():
print 'hello'
g=f(g)
Ma, ho avuto questo codice, che utilizzi contextlib.contextmanager:
@contextlib.contextmanager
def f():
print 1
yield
print 2
with f:
print 3
che funziona e le rese 1 3 2
E quando ho cercato di trasformarla in
def f():
print 1
yield
print 2
f=contextlib.contextmanager(f)
with f:
print 3
ho AttributeError: 'function' object has no attribute '__exit__'
Che cosa mi manca? c'è qualche magia nera in particolare in contextlib.contextmanager o devo fraintendere come decoratori lavorano in generale?
Soluzione
Sì, decoratore è esattamente uguale a chiamare una funzione e l'assegnazione al valore restituito
In questo caso l'errore viene perché non si sta chiamando la funzione, codice in modo corretto sarebbe
def f():
print 1
yield
print 2
f=contextlib.contextmanager(f)
with f():
print 3
anche io non sono sicuro se testato codice, perché il codice decoratore hai dato non riuscirà a causa della stessa ragione
@contextlib.contextmanager
def f():
print 1
yield
print 2
with f:
print 3
Errore:
with f:
AttributeError: 'function' object has no attribute '__exit__'