2015-07-20 28 views
11

我想在Windows 7 64位和Python 3.4.3aysncio不能在Windows

標準輸入異步讀讀標準輸入我試圖通過SO answer這個啓發:

import asyncio 
import sys 


def reader(): 
    print('Received:', sys.stdin.readline()) 


loop = asyncio.get_event_loop() 
task = loop.add_reader(sys.stdin.fileno(), reader) 
loop.run_forever() 
loop.close() 

然而,產生了OSError: [WInError 100381] An operation was attempted on something that is not a socket

像文件一樣的對象stdin可以包裝在一個類中給它一個套接字的API嗎?我有asked this question separately,但如果解決方法很簡單,請在這裏回答。

假設我不能完成一個類似文件的對象,使其成爲插口,我試圖用流作爲啓發this gist

import asyncio 
import sys 


@asyncio.coroutine 
def stdio(loop): 
    reader = asyncio.StreamReader(loop=loop) 
    reader_protocol = asyncio.StreamReaderProtocol(reader) 
    yield from loop.connect_read_pipe(lambda: reader_protocol, sys.stdin) 


@asyncio.coroutine 
def async_input(loop): 
    reader = yield from stdio(loop) 
    line = yield from reader.readline() 
    return line.decode().replace('\r', '').replace('\n', '') 


@asyncio.coroutine 
def main(loop): 
    name = yield from async_input(loop) 
    print('Hello ', name) 


loop = asyncio.get_event_loop() 
loop.run_until_complete(main(loop)) 
loop.close() 

這提出了一個在NotImplementedErrorasyncio.base_events._make_read_pipe_transport

請指教如何在Windows上使用asyncio來讀取stdin ...

回答

10

NotImplementedError異常提出,因爲connect pipes coroutines不是su由SelectorEventLoop導出,這是在asyncio上設置的默認事件循環。您需要使用ProactorEventLoop來支持Windows上的管道。但是,它仍然不起作用,因爲顯然connect_read_pipeconnect_write_pipe函數不支持stdin/stdout/stderr或Windows中的文件,如Python 3.5.1。

使用異步行爲從stdin中讀取的一種方法是使用帶有循環的run_in_executor方法的線程。下面是參考一個簡單的例子:

import asyncio 
import sys 

async def aio_readline(loop): 
    while True: 
     line = await loop.run_in_executor(None, sys.stdin.readline) 
     print('Got line:', line, end='') 

loop = asyncio.get_event_loop() 
loop.run_until_complete(aio_readline(loop)) 
loop.close() 

在功能sys.stdin.readline()被稱爲由loop.run_in_executor方法另一個線程內的例子。線程一直處於阻塞狀態,直到stdin收到一個換行符,同時該循環可以自由執行其他協程,如果它們存在的話。