aysncio无法读取Windows上的标准input

我正在尝试在Windows 7 64位和Python 3.4.3上asynchronous读取stdin

我尝试了这个启发的答案 :

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吗? 我已经单独提出了这个问题 ,但是如果解决方法很简单,请在这里回答。

假设我不能包装一个类似文件的对象来使它成为一个套接字,我尝试使用stream的灵感来源于这个要点 :

 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() 

这在asyncio.base_events._make_read_pipe_transport中引发了NotImplementedError

请告知如何阅读stdin在Windows上使用asyncio

引发NotImplementedError异常是因为SelectorEventLoop不支持连接管道协程 ,这是在asyncio设置的默认事件循环。 您需要使用ProactorEventLoop来支持Windows上的管道。 但是,它仍然不起作用,因为显然connect_read_pipeconnect_write_pipe函数不支持stdin / stdout / stderr或Windows中的文件,如Python 3.5.1。

stdin读取异步行为的run_in_executor方法是使用循环的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接收到一个换行符,同时循环可以自由地执行其他的协程。