2017-04-01 58 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