从 contextlib asynccontextmanager 产生 future 不安全吗?

问题描述 投票:0回答:1

我遇到一个问题,我需要检查日志文件中执行的两点之间是否发生了某些情况。

目前我这样做:

print("start")
# do something here
print("end")
res = await check_log(...) # check in the log if something's happened 
                        # between start and end and return the line if so

我想知道是否可以使用一个如下所示的 contextlib asynccontextmanager:

class foo():
    def __init__(self, ...):
    ...

    @asynccontextmanager
    async def bar(self):
        print("start")
        fut = asyncio.Future()
        yield fut
        print("end")
        res = await check_log(...)
        fut.set_result(res)

我这样称呼它,其中类包含我必须传递给 check_log 的变量:

obj = foo(...)

async with obj.bar() as b:
    # do something here

res = b.result()

这有什么根本上不安全或错误的地方吗?如果是这样,有更好的方法吗?我知道使用常规上下文管理器,您可以通过设置属性来解决它,尽管我不确定 contextlib 是否可以。

python python-asyncio contextmanager
1个回答
0
投票

这看起来完全有效并且没问题。 要记住的基本一点是,只有在执行上下文管理器中的

with
方法之后,才会在包含
__aexit__
块的代码中继续执行 - 这意味着运行方法中经过
yield fut
的部分,并且因此,
await check_log(...)
执行完成。

如果您希望

check_log
with
块之后的块同时执行,通过将创建
check_log
更改为任务,并将其
done callback
设置为将设置
 的函数,这同样容易做到fut
的结果 - 那么,在这个例子中,只要有人想要检查该结果,就可以等待
b
。否则,就这样好了。 (请把
yield
语句及其后面的块放在
try-finally
复合体中)

© www.soinside.com 2019 - 2024. All rights reserved.