è un decoratore in python esattamente lo stesso di chiamare una funzione su una funzione?

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

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?

È stato utile?

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__'
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top