aysncio无法读取Windows上的stdin

时间:2015-07-20 06:41:20

标签: python windows python-3.x asynchronous stdin

我试图在Windows 7 64位和Python 3.4.3上异步读取stdin

我尝试了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()

这会在NotImplementedError

中引发asyncio.base_events._make_read_pipe_transport

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

1 个答案:

答案 0 :(得分:15)

引发NotImplementedError异常是因为SelectorEventLoop不支持connect pipes coroutinesasyncioconnect_read_pipe上设置的默认事件循环。您需要使用ProactorEventLoop来支持Windows上的管道。但是,它仍然无效,因为显然connect_write_pipestdin函数不支持stdout / stderr / stdin或Windows中的文件Python 3.5.1。

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。线程保持阻塞状态,直到/* iPhone 6 landscape */ @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 2) { /* Your CSS */ } /* iPhone 6 portrait */ @media only screen and (min-device-width: 375px) and (max-device-width: 667px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 2) { /* Your CSS */ } /* iPhone 6 Plus landscape */ @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (orientation: landscape) and (-webkit-min-device-pixel-ratio: 3) { /* Your CSS */ } /* iPhone 6 Plus portrait */ @media only screen and (min-device-width: 414px) and (max-device-width: 736px) and (orientation: portrait) and (-webkit-min-device-pixel-ratio: 3) { /* Your CSS */ } /* iPhone 6 and 6 Plus */ @media only screen and (max-device-width: 640px), only screen and (max-device-width: 667px), only screen and (max-width: 480px) { /* Your CSS */ } 收到换行符,同时循环可以自由执行其他协同程序(如果它们存在)。