我在QT-Application中使用来自请求模块的生成器函数,与请求流示例中的几乎相同:
import json
import requests
def get_stream():
r = requests.get('http://httpbin.org/stream/20', stream=True)
for line in r.iter_lines():
if line:
yield json.loads(line)
def consume_stream():
for message in get_stream():
#do something
但是,当没有传入响应时(例如来自Twitters Streaming API的不定期传入的推文),生成器get_stream
将阻止consume_stream
方法。
这可能发生在任何情况下,即生成器不立即生成,但是要等待传入消息等,从而阻止消费者。
在Python中是否有任何模式可以以非阻塞方式使用生成器,即如果生成器生成,处理结果,否则在发生下一个结果之前执行其他操作?
答案 0 :(得分:2)
看看producer-consumer pattern。它通常使用Queue
在python中实现。
生成器通常在线程或其他进程中运行(Queue
支持),只需将消息放入队列即可。消费者无论何时感觉都会从队列中弹出消息。此操作支持timeout
参数。
答案 1 :(得分:1)
正如Simeon在评论中提出的那样,它不能像你在你的例子中描述的那样简单。你需要注意一些细节。根据您的使用情况,有不同的解决方案或多或少有意义。您没有提供有关您真正想做的事情的详细信息,因此我将以http://twistedmatrix.com/trac/wiki/QTReactor为例向您发送信息。有一个不同的解决方案/框架实现异步消息队列。而且我认为,这就是你要找的东西。
答案 2 :(得分:1)
如果您控制生成器函数,一个解决方案是在超时期限后抛出异常。也许有些事情如下:
def get_stream(timeout=None):
while message=read_message(timeout=timout):
yield message
然后,如果发生超时条件,read_message会抛出一个TimeOutException。
当然,您仍然需要处理何时/如何重试/恢复的后勤工作。
答案 3 :(得分:0)
您可以使用自python 3.6 https://www.python.org/dev/peps/pep-0525/起的异步生成器
@bot.command()
async def send_typing(ctx):
await ctx.trigger_typing()
await asyncio.sleep(10)
await ctx.send('End of typing')