est un décorateur en python exactement la même chose que d'appeler une fonction sur une fonction?

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

Question

Je pensais que faire

@f
def g():
   print 'hello'

est exactement le même que

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

Mais, j'avais ce code, qui utilise contextlib.contextmanager:

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

qui fonctionne et les rendements 1 3 2

Et quand j'ai essayé de le changer en

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

Je reçois AttributeError: 'function' object has no attribute '__exit__'

Qu'est-ce que je manque? est-il un peu de magie noire spécifiquement dans contextlib.contextmanager, ou dois-je mal comprendre comment les décorateurs travaillent en général?

Était-ce utile?

La solution

Oui, décorateur est exactement la même que l'appel d'une fonction et l'affectation à la valeur retournée

Dans cette erreur est le cas parce que vous n'êtes pas appeler la fonction, le code de manière correcte serait

def f():
    print 1
    yield
    print 2

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

aussi je ne sais pas si vous avez testé le code, parce que le code de décorateur vous avez donné échouera en raison de la raison même

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

Erreur:

    with f:
AttributeError: 'function' object has no attribute '__exit__'
Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top