Estoy tratando de leer stdin de forma asíncrona en Windows 7 de 64 bits y Python 3.4.3
Intenté esto inspirado por una respuesta SO :
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()
Sin embargo, genera un OSError: [WInError 100381] An operation was attempted on something that is not a socket
.
¿Podría un objeto similar a un archivo como stdin
ser envuelto en una clase para darle la API de un socket? He hecho esta pregunta por separado , pero si la solución es simple, responda aquí.
Suponiendo que no puedo envolver un objeto similar a un archivo para convertirlo en un socket, intenté usar flujos inspirados en esta esencia :
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()
Y eso genera un NotImplementedError
en asyncio.base_events._make_read_pipe_transport
Por favor avise cómo leer stdin
usando asyncio
en Windows …
La excepción NotImplementedError
se NotImplementedError
porque las líneas de conexión de tuberías no son compatibles con SelectorEventLoop
, que es el bucle de eventos predeterminado establecido en asyncio
. ProactorEventLoop
usar un ProactorEventLoop
para admitir tuberías en Windows. Sin embargo, aún no funcionaría porque aparentemente las funciones connect_read_pipe
y connect_write_pipe
no admiten stdin
/ stdout
/ stderr
o archivos en Windows como Python 3.5.1.
Una forma de leer desde stdin
con un comportamiento asíncrono es usar un hilo con el método run_in_executor
del bucle. Aquí hay un ejemplo simple para referencia:
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()
En el ejemplo, la función sys.stdin.readline()
es llamada dentro de otro hilo por el método loop.run_in_executor
. El hilo permanece bloqueado hasta que stdin
recibe un salto de línea, mientras tanto, el bucle es libre de ejecutar otras rutinas si existieran.