gpt4 book ai didi

python - 如何重用自定义的@contextlib.contextmanager?

转载 作者:太空宇宙 更新时间:2023-11-03 14:59:23 25 4
gpt4 key购买 nike

我正在尝试创建一个包装器来使上下文对象成为可选的。当条件为真时,事物应该表现得像包装的上下文对象,否则它应该表现得像无操作上下文对象。此示例适用于使用一次包装对象,但失败了,它被重新使用。

例子:

import contextlib
from threading import Lock

@contextlib.contextmanager
def conditional_context(context, condition):
if condition and context:
with context:
yield
else:
yield

use_locking = False
lock = conditional_context(Lock(), use_locking)
with lock:
print('Foo')
with lock:
print('Bar')

输出:

Foo
Traceback (most recent call last):
File "example.py", line 16, in <module>
with lock:
File "/usr/lib/python3.5/contextlib.py", line 61, in __enter__
raise RuntimeError("generator didn't yield") from None
RuntimeError: generator didn't yield

最佳答案

你不能用 contextlib.contextmanager 做到这一点。正如在传递中提到的the docs , 由 contextmanager 创建的上下文管理器是一次性的。

如果您希望同一个对象在多个 with 语句中可重用,则必须使用 __enter____exit__ 方法编写自己的类:

from threading import Lock


class ConditionalContext:

def __init__(self, context, condition):
self._context = context
self._condition = condition

def __enter__(self, *args, **kwargs):
if self._condition:
self._context.__enter__(*args, **kwargs)

def __exit__(self, *args, **kwargs):
if self._condition:
self._context.__exit__(*args, **kwargs)


use_locking = False
lock = ConditionalContext(Lock(), use_locking)
with lock:
print('Foo')
with lock:
print('Bar')

关于python - 如何重用自定义的@contextlib.contextmanager?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39554981/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com