Это декоратор в Python точно такой же, как позвонить в функцию на функцию?
-
28-09-2019 - |
Вопрос
Я думал, что делает
@f
def g():
print 'hello'
точно так же, как
def g():
print 'hello'
g=f(g)
Но у меня был этот код, который использует contextlib.contextmanager:
@contextlib.contextmanager
def f():
print 1
yield
print 2
with f:
print 3
который работает и урожай 1 3 2
И когда я пытался изменить его в
def f():
print 1
yield
print 2
f=contextlib.contextmanager(f)
with f:
print 3
я получил AttributeError: 'function' object has no attribute '__exit__'
Что мне не хватает? Есть ли какая-то черная магия в Contextlib.contextManager, или я неправильно понимаю, как декораторы работают в целом?
Решение
Да, декоратор точно такой же, как вызывая функцию и назначение возвращенной стоимости
В этом случае ошибка приходит, потому что вы не вызываете функцию, поэтому правильный код будет
def f():
print 1
yield
print 2
f=contextlib.contextmanager(f)
with f():
print 3
Также я не уверен, если вы протестируете код, потому что код декоратора, который вы дали, потерпят неудачу из-за такой же причины
@contextlib.contextmanager
def f():
print 1
yield
print 2
with f:
print 3
Ошибка:
with f:
AttributeError: 'function' object has no attribute '__exit__'
Не связан с StackOverflow