开发者

is a decorator in python exactly the same as calling a function on a function?

开发者 https://www.devze.com 2023-01-04 13:20 出处:网络
I thought that doing @f def g(): print \'hello\' is exactly the same as def g(): print \'hello\' g=f(g) But, I had this code, that uses contextlib.contextmanager:

I thought that doing

@f
def g():
   print 'hello'

is exactly the same as

def g():
   print 'hello'
g=f(g)

But, I had this code, that uses contextlib.contextmanager:

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

which works and yields 1开发者_运维技巧 3 2

And when I tried to change it into

def f():
    print 1
    yield
    print 2
f=contextlib.contextmanager(f)
with f:
    print 3

I get AttributeError: 'function' object has no attribute '__exit__'

What am I missing? is there some black magic specifically in contextlib.contextmanager, or do i misunderstand how decorators work in general?


Yes, decorator is exactly same as calling a function and assigning to returned value

In this case error comes because you are not calling function, so correct code would be

def f():
    print 1
    yield
    print 2

f=contextlib.contextmanager(f)
with f():
    print 3

also I am not sure if you tested code, because decorator code you have given will fail due to same reason

@contextlib.contextmanager
def f():
    print 1
    yield
    print 2
with f:
    print 3

Error:

    with f:
AttributeError: 'function' object has no attribute '__exit__'
0

精彩评论

暂无评论...
验证码 换一张
取 消