Python异步:在做其他事情的同时等待标准输入

新手上路,请多包涵

我正在尝试创建一个 WebSocket 命令行客户端,它等待来自 WebSocket 服务器的消息,但同时等待用户输入。

每隔一秒定期轮询多个在线资源在服务器上运行良好(在这个例子中运行在 localhost:6789 的服务器),但不是使用 Python 的正常 sleep() 方法,它使用 asyncio.sleep() ,这是有道理的,因为睡眠和异步睡眠不是一回事,至少不是在幕后。

同样,等待用户输入和异步等待用户输入不是一回事,但我不知道如何异步等待用户输入,就像我可以异步等待任意秒数一样,所以客户端可以在等待用户输入的同时处理来自 WebSocket 服务器的传入消息。

else monitor_cmd() 子句中的评论希望能解释我的意思:

 import asyncio
import json
import websockets

async def monitor_ws():
    uri = 'ws://localhost:6789'
    async with websockets.connect(uri) as websocket:
        async for message in websocket:
            print(json.dumps(json.loads(message), indent=2, sort_keys=True))

async def monitor_cmd():
    while True:

        sleep_instead = False

        if sleep_instead:
            await asyncio.sleep(1)
            print('Sleeping works fine.')
        else:
            # Seems like I need the equivalent of:
            # line = await asyncio.input('Is this your line? ')
            line = input('Is this your line? ')
            print(line)
try:
    asyncio.get_event_loop().run_until_complete(asyncio.wait([
        monitor_ws(),
        monitor_cmd()
    ]))
except KeyboardInterrupt:
    quit()

这段代码只是无限期地等待输入,同时什么都不做,我明白为什么。我不明白的是如何解决它。 :)

当然,如果我以错误的方式思考这个问题,我也很乐意学习如何补救。

原文由 Teekin 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 1.2k
2 个回答

您可以使用 aioconsole 第三方包以异步友好的方式与 stdin 交互:

 line = await aioconsole.ainput('Is this your line? ')

原文由 user4815162342 发布,翻译遵循 CC BY-SA 4.0 许可协议

aioconsole 大量借用,如果你宁愿避免使用外部库,你可以定义自己的异步输入函数:

 async def ainput(string: str) -> str:
    await asyncio.get_event_loop().run_in_executor(
            None, lambda s=string: sys.stdout.write(s+' '))
    return await asyncio.get_event_loop().run_in_executor(
            None, sys.stdin.readline)

原文由 mfurseman 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进