2017-04-01 57 views
0

我尝试尝试为命令行编写某种渲染器,该渲染器应该能够从stdin和其他数据源使用asyncioblessed打印数据,这是一个改进版本蟒蛇的祝福。从stdin和其他来源异步写入控制台

这是我到目前为止有:

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按预期工作。当我使用类似pingpong代替input_reader时,一切都很好。

这是它的外观输入“乒乓”的时候,但如果需要十秒写“乓”:

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

回答

0

好像有福未建与ASYNCIO正常工作:inkey()是阻塞方法。这将阻止任何其他轮回。

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

+0

对于'timeout'= 0的'inkey' [文档](https://blessed.readthedocs.io/en/latest/overview.html#inkey)表示它不阻塞。但行为不会改变。你有任何建议干净的解决方案?它不应该被祝福是负责从标准输入读数 - 我主要是想用它来输出控制。 – dahrens