从stdin和其他来源异步写入控制台

时间:2017-04-01 10:32:33

标签: python-3.x python-asyncio python-blessings

我尝试为命令行编写某种渲染器,该命令行应该能够使用stdinasyncioblessed和其他数据源打印数据,这是改进版的python-blessings。

这是我到目前为止所做的:

import asyncio
from blessed import Terminal

@asyncio.coroutine
def render(term):
    while True:
        received = yield
        if received:
            print(term.bold + received + term.normal)

async def ping(renderer):
    while True:
        renderer.send('ping')
        await asyncio.sleep(1)

async def input_reader(term, renderer):
    while True:
        with term.cbreak():
            val = term.inkey()
            if val.is_sequence:
               renderer.send("got sequence: {0}.".format((str(val), val.name, val.code)))
            elif val:
               renderer.send("got {0}.".format(val))

async def client():
    term = Terminal()
    renderer = render(term)
    render_task = asyncio.ensure_future(renderer)
    pinger = asyncio.ensure_future(ping(renderer))
    inputter = asyncio.ensure_future(input_reader(term, renderer))
    done, pending = await asyncio.wait(
        [pinger, inputter, renderer],
        return_when=asyncio.FIRST_COMPLETED,
    )
    for task in pending:
        task.cancel()

if __name__ == '__main__':
    asyncio.get_event_loop().run_until_complete(client())
    asyncio.get_event_loop().run_forever()

出于学习和测试目的,只有一个转储ping每秒发送'ping'和另一个例程,它应该抓取键输入并将它们发送到我的渲染器。

但ping只在命令行中出现一次使用此代码,并且input_reader按预期工作。当我用与pong类似的ping替换input_reader时,一切都很好。

这就是打字' pong'时的样子,虽然如果需要十秒钟才能写出' pong':

$ python async_term.py
ping
got p.
got o.
got n.
got g.

1 个答案:

答案 0 :(得分:0)

看起来好像无法使用asyncio正常工作:inkey()是一种阻止方法。这将阻止任何其他的例程。

您可以使用kbhit()await asyncio.sleep()的循环来控制其他协同程序 - 但这不是一个干净的asyncio解决方案。