est un décorateur en python exactement la même chose que d'appeler une fonction sur une fonction?
-
28-09-2019 - |
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?
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__'