编程语言
首页 > 编程语言> > python中的装饰器与在函数上调用函数完全相同吗?

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

作者:互联网

我以为

@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:“函数”对象没有属性“ __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__'

标签:contextmanager,decorator,python
来源: https://codeday.me/bug/20191024/1917217.html