python中的装饰器与调用函数的函数完全相同吗?

ola*_*ndo 3 python decorator contextmanager

我以为这样做

@f
def g():
   print 'hello'
Run Code Online (Sandbox Code Playgroud)

与...完全相同

def g():
   print 'hello'
g=f(g)
Run Code Online (Sandbox Code Playgroud)

但是,我有这个代码,它使用contextlib.contextmanager:

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3
Run Code Online (Sandbox Code Playgroud)

有效和收益 1 3 2

当我试图改变它

def f():
    print 1
    yield
    print 2
f=contextlib.contextmanager(f)
with f:
    print 3
Run Code Online (Sandbox Code Playgroud)

我明白了 AttributeError: 'function' object has no attribute '__exit__'

我错过了什么?在contextlib.contextmanager中是否有一些黑魔法,或者我是否误解了装饰器的工作原理?

Anu*_*yal 5

是的,装饰器与调用函数和分配返回值完全相同

在这种情况下,错误来自因为您没有调用函数,所以正确的代码将是

def f():
    print 1
    yield
    print 2

f=contextlib.contextmanager(f)
with f():
    print 3
Run Code Online (Sandbox Code Playgroud)

我也不确定你是否测试过代码,因为你给出的装饰器代码会因同样的原因而失败

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3
Run Code Online (Sandbox Code Playgroud)

错误:

    with f:
AttributeError: 'function' object has no attribute '__exit__'
Run Code Online (Sandbox Code Playgroud)