Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/python-3.x/17.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将async for与if条件结合以中断mid Wait的正确方法是什么?_Python_Python 3.x_Asynchronous_Python Asyncio - Fatal编程技术网

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
将被取消。在第二种情况下,它将继续在后台运行,只会在完成后被丢弃。前者可能更干净。两种解决方案都很有效,非常感谢!