Python 将async for与if条件结合以中断mid Wait的正确方法是什么?
如果我有一个使用异步生成器项的协同程序,那么从外部条件终止该循环的“最佳”方法是什么 想想这个,Python 将async for与if条件结合以中断mid Wait的正确方法是什么?,python,python-3.x,asynchronous,python-asyncio,Python,Python 3.x,Asynchronous,Python Asyncio,如果我有一个使用异步生成器项的协同程序,那么从外部条件终止该循环的“最佳”方法是什么 想想这个, 而非自身。关机事件。是否已设置() 与self.external_lib_客户端作为客户端异步: 客户端中消息的异步: 如果设置了self.shutdown\u事件(): 打破 等待自我处理(消息) 如果我设置shutdown\u事件它将中断while循环,但直到async for循环处理下一条消息。为迭代器构造async的正确方法是什么,以便在迭代器之间满足条件时可以短路,从而产生结果 是否有一
而非自身。关机事件。是否已设置()
与self.external_lib_客户端作为客户端异步:
客户端中消息的异步:
如果设置了self.shutdown\u事件():
打破
等待自我处理(消息)
如果我设置shutdown\u事件
它将中断while循环,但直到async for
循环处理下一条消息
。为迭代器构造async的正确方法是什么,以便在迭代器之间满足条件时可以短路,从而产生结果
是否有一种标准的方法来添加超时
?一种方法是将迭代移动到异步定义
并使用取消:
async def iterate(client):
async for message in client:
# shield() because we want cancelation to cancel retrieval
# of the next message, not ongoing handling of a message
await asyncio.shield(self.handle(message))
async with self.external_lib_client as client:
iter_task = asyncio.create_task(iterate(client))
shutdown_task = asyncio.create_task(self.shutdown_event.wait())
await asyncio.wait([iter_task, shutdown_task],
return_when=asyncio.FIRST_COMPLETED)
if iter_task.done():
# iteration has completed, access result to propagate the
# exception if one was raised
iter_task.result()
shutdown_task.cancel()
else:
# shutdown was requested, cancel iteration
iter_task.cancel()
另一种方法是将shutdown\u事件
转换为一次性异步流,并使用它来监视这两个事件。这样,当发出关闭事件信号时,for
循环将获得一个对象,并且可以中断循环,而无需费心等待下一条消息:
# a stream that just yields something (the return value of `wait()`)
# when shutdown_event is set
done_stream = aiostream.stream.just(self.shutdown_event.wait())
async with self.external_lib_client as client, \
aiostream.stream.merge(done_stream, client).stream() as stream:
async for message in stream:
# the merged stream will provide a bogus value (whatever
# `shutdown_event.wait()` returned) when the event is set,
# so check that before using `message`:
if self.shutdown_event.is_set():
break
await self.handle(message)
注意:由于问题中的代码不可运行,因此上述示例未经测试。在循环体中添加if
不会有帮助。您需要更改迭代器本身,可能需要使用某种超时包装迭代器。太棒了aiostream
在我的任何搜索中都没有返回。Thanks@blakev请注意,这两个选项之间的区别在于,在第一个选项中,如果发生停机事件,\uuuuuanext\uuuuu
将被取消。在第二种情况下,它将继续在后台运行,只会在完成后被丢弃。前者可能更干净。两种解决方案都很有效,非常感谢!