gpt4 book ai didi

Python 一个类中有多个上下文管理器

转载 作者:行者123 更新时间:2023-12-01 04:37:19 25 4
gpt4 key购买 nike

我希望能够编写这样的代码:

with obj.in_batch_mode:
obj.some_attr = "some_value"
obj.some_int = 142
...

当我希望 obj 等待发送有关其自身的更新,直到多个作业完成时。我在 __setattr__ 上有一些钩子(Hook),需要一些时间才能运行,并且可以将更改一起发送。

我不想使用这样的代码,因为它增加了忘记离开batch_mode的风险(这是 with 关键字的优点):

obj.enter_batch_mode()
obj.some_attr = "some_value"
obj.some_int = 142
...
obj.exit_batch_mode()

我一直无法弄清楚如何实现这一点。仅仅输入 with obj: (并且简单地在 obj 上实现 with)不会读到任何接近描述性的内容。

最佳答案

通常,实现上下文管理器的一个非常简单的方法是使用 contextlib模块。编写上下文管理器变得就像编写单个yield 生成器一样简单。在yield取代__enter__方法之前,yield出来的对象是__enter__的返回值,yield之后的部分就是__exit__方法。类上的任何函数都可以是上下文管理器,它只需要这样装饰即可。例如,采用这个简单的 ConsoleWriter 类:

from contextlib import contextmanager

from sys import stdout
from io import StringIO
from functools import partial

class ConsoleWriter:

def __init__(self, out=stdout, fmt=None):
self._out = out
self._fmt = fmt

@property
@contextmanager
def batch(self):
original_out = self._out
self._out = StringIO()
try:
yield self
except Exception as e:
# There was a problem. Ignore batch commands.
# (do not swallow the exception though)
raise
else:
# no problem
original_out.write(self._out.getvalue())
finally:
self._out = original_out

@contextmanager
def verbose(self, fmt="VERBOSE: {!r}"):
original_fmt = self._fmt
self._fmt = fmt
try:
yield self
finally:
# don't care about errors, just restore end
self._fmt = original_fmt

def __getattr__(self, attr):
"""creates function that writes capitalised attribute three times"""
return partial(self.write, attr.upper()*3)


def write(self, arg):
if self._fmt:
arg = self._fmt.format(arg)
print(arg, file=self._out)

使用示例:

writer = ConsoleWriter()
with writer.batch:
print("begin batch")
writer.a()
writer.b()
with writer.verbose():
writer.c()
print("before reentrant block")
with writer.batch:
writer.d()
print("after reentrant block")
print("end batch -- all data is now flushed")

输出:

begin batch
before reentrant block
after reentrant block
end batch -- all data is now flushed
AAA
BBB
VERBOSE: 'CCC'
DDD

关于Python 一个类中有多个上下文管理器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31505946/

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