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

发布于 2024-09-06 21:25:27 字数 621 浏览 0 评论 0原文

我认为这样做

@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' 对象没有属性 '__exit__'

我缺少什么? 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

青瓷清茶倾城歌 2024-09-13 21:25:27

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

在这种情况下会出现错误,因为您没有调用函数,所以正确的代码

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__'

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__'
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文