我需要异步读取StdIn以获取消息(json由\r\n终止),并在处理异步后将更新的消息写入StdOut。
现在我正在同步地做:
class SyncIOStdInOut():
def write(self, payload: str):
sys.stdout.write(payload)
sys.stdout.write('\r\n')
sys.stdout.flush()
def read(self) -> str:
payload=sys.stdin.readline()
return payload
如何异步地做同样的事情?
2条答案
按热度按时间izkcnapc1#
下面是使用asyncio streams(对于Unix)将
stdin
回显到stdout
的示例。作为一个现成的解决方案,您可以使用aioconsole库。它实现了类似的方法,但也提供了
input
、print
、exec
和code.interact
的其他有用的异步等效方法:更新:
让我们试着弄清楚函数
connect_stdin_stdout
是如何工作的。1.获取当前事件循环:
1.创建
StreamReader
示例。通常,
StreamReader/StreamWriter
类不打算直接示例化,而应该仅作为open_connection()
和start_server()
等函数的结果使用。StreamReader
为某些数据流提供缓冲异步接口。一些源代码(库代码)调用其函数,如feed_data
,feed_eof
,数据被缓冲,可以使用文档中的接口协程read()
,readline()
等读取。1.创建
StreamReaderProtocol
示例。这个类是从
asyncio.Protocol
和FlowControlMixin
派生而来的,有助于在Protocol
和StreamReader
之间进行适配。它覆盖Protocol
方法,如data_received
,eof_received
,并调用StreamReader
方法feed_data
。1.在事件循环中注册标准输入流
stdin
。connect_read_pipe
函数接受一个类似文件的对象作为pipe
参数。stdin
是类似文件的对象。从现在开始,从stdin
读取的所有数据将落入StreamReaderProtocol
,然后传递到StreamReader
1.在事件循环中注册标准输出流
stdout
。在
connect_write_pipe
中,您需要传递一个协议工厂,该工厂创建协议示例,为StreamWriter.drain()
实现流控制逻辑。这个逻辑在FlowControlMixin
类中实现。StreamReaderProtocol
也继承了它。1.创建
StreamWriter
示例。该类使用函数
write()
、writelines()
等转发传递给它的数据。到底层的transport
。protocol
用于支持drain()
函数,以等待底层传输已刷新其内部缓冲区并可用于再次写入的时刻。reader
是一个可选参数,可以是None
,它也用于支持drain()
函数,在这个函数的开始,它会检查是否为读取器设置了异常,例如,由于连接丢失(与套接字和双向连接相关),那么drain()
也会抛出异常。您可以在这个伟大的answer中阅读更多关于
StreamWriter
和drain()
函数的信息。更新二:
要读取带有
\r\n
分隔符的行,可以使用readuntilmpgws1up2#
这是从stdin异步读取的另一种方式(一次读取一行)。