我以为在做
@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中是否有一些黑魔法,或者我是否误解了装饰器的工作原理?
答案 0 :(得分:5)
是的,装饰器与调用函数和分配返回值完全相同
在这种情况下出现错误是因为你没有调用函数,因此正确的代码将是
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__'