Это декоратор в Python точно такой же, как позвонить в функцию на функцию?

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

Вопрос

Я думал, что делает

@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__'
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top