更改 Python 3 中打开 stdin/stdout 的方式

Nik*_*nes 9 python python-3.x

在最近的Python 3.x中,默认行为是以通用换行符模式( )open打开文件,这意味着如果我打开这样的文件:newline=None

\n\n
f = open("file.txt")\n
Run Code Online (Sandbox Code Playgroud)\n\n

那么"\\n"当使用f.readline()for line in f:等时,所有不同的行结尾(CRLF/CR/LF)都会被转换成。

\n\n

但是,在处理 时sys.stdin,不同的行结尾不会转换(至少在 Linux 上,读取 CRLF 文件意味着 的结果以sys.stdin.readline()结尾"\\r\\n")。这意味着sys.stdin使用不同的设置打开它newline。有什么方法可以影响用于打开的参数吗sys.stdin

\n\n

更一般地说,Python 中是否有类似于 Perl 的东西binmode可以改变读取sys.stdin/写入的sys.stdout工作方式?

\n\n

需要明确的是,我知道我可以自己进行 CRLF\xe2\x86\x92LF 转换。这不是这个问题的目的。

\n

aba*_*ert 7

没有办法完全替代 Python 将 stdin 和 stdout 管道包装在sys.stdin和中的方式sys.stdout。(有一些有限的控制,例如option`-u,但仅此而已。)

\n\n

然而,您还要求其他多种东西,所有这些都是可能的,其中一些可能就是您想要的。

\n\n
\n\n

首先,sys.stdin只是一个普通的TextIOWrapper,如open(在文本模式下)返回的那样。这意味着您可以访问其底层二进制对象,或者其下面的原始无缓冲文件对象,或者其下面的操作系统文件描述符,与任何其他文本文件相同:

\n\n
sys.stdin.buffer\nsys.stdin.buffer.raw\nsys.stdin.fileno()\n
Run Code Online (Sandbox Code Playgroud)\n\n

通常,这就是您所需要的。您不会想实际替换sys.stdin = sys.stdin.buffer. 这会破坏input模块fileinput,谁知道文本文件还需要什么stdin。但是您可以使用sys.stdin.buffer代替sys.stdin,它大致相当于我认为您从 perl 中寻找的内容binmode

\n\n
\n\n

如果您希望TextIOWrapper在同一个底层文件中包含不同的选项,您也可以这样做。

\n\n

对于最简单的情况,最简单的方法就是调用open您想要调用的方式open,传递文件描述符:

\n\n
sin = open(sys.stdin.fileno(), <your open arguments here>)\n
Run Code Online (Sandbox Code Playgroud)\n\n

对于不太琐碎的情况,您可能需要阅读TextIOWrapper文档(以及模块BufferedReader中的其他类型io)并以您想要的方式准确包装您想要的部分。但通常情况下,open就足够了。

\n\n

无论哪种方式,您都可以使用sin来代替sys.stdin.

\n\n

或者,由于现在这一个非常好的TextIOWrapper(假设您open在文本模式下编辑),因此替换sys.stdin安全且合理的:

\n\n
sys.stdin = sin\n
Run Code Online (Sandbox Code Playgroud)\n\n

\xe2\x80\xa6 和现在input等,将继续工作 \xe2\x80\x94 并将按照您希望的方式工作。

\n