在最近的Python 3.x中,默认行为是以通用换行符模式( )open打开文件,这意味着如果我打开这样的文件:newline=None
f = open("file.txt")\nRun Code Online (Sandbox Code Playgroud)\n\n那么"\\n"当使用f.readline()、for line in f:等时,所有不同的行结尾(CRLF/CR/LF)都会被转换成。
但是,在处理 时sys.stdin,不同的行结尾不会转换(至少在 Linux 上,读取 CRLF 文件意味着 的结果以sys.stdin.readline()结尾"\\r\\n")。这意味着sys.stdin使用不同的设置打开它newline。有什么方法可以影响用于打开的参数吗sys.stdin?
更一般地说,Python 中是否有类似于 Perl 的东西binmode可以改变读取sys.stdin/写入的sys.stdout工作方式?
需要明确的是,我知道我可以自己进行 CRLF\xe2\x86\x92LF 转换。这不是这个问题的目的。
\n没有办法完全替代 Python 将 stdin 和 stdout 管道包装在sys.stdin和中的方式sys.stdout。(有一些有限的控制,例如option`-u,但仅此而已。)
然而,您还要求其他多种东西,所有这些都是可能的,其中一些可能就是您想要的。
\n\n首先,sys.stdin只是一个普通的TextIOWrapper,如open(在文本模式下)返回的那样。这意味着您可以访问其底层二进制对象,或者其下面的原始无缓冲文件对象,或者其下面的操作系统文件描述符,与任何其他文本文件相同:
sys.stdin.buffer\nsys.stdin.buffer.raw\nsys.stdin.fileno()\nRun Code Online (Sandbox Code Playgroud)\n\n通常,这就是您所需要的。您不会想实际替换sys.stdin = sys.stdin.buffer. 这会破坏input模块fileinput,谁知道文本文件还需要什么stdin。但是您可以使用sys.stdin.buffer代替sys.stdin,它大致相当于我认为您从 perl 中寻找的内容binmode。
如果您希望TextIOWrapper在同一个底层文件中包含不同的选项,您也可以这样做。
对于最简单的情况,最简单的方法就是调用open您想要调用的方式open,传递文件描述符:
sin = open(sys.stdin.fileno(), <your open arguments here>)\nRun Code Online (Sandbox Code Playgroud)\n\n对于不太琐碎的情况,您可能需要阅读TextIOWrapper文档(以及模块BufferedReader中的其他类型io)并以您想要的方式准确包装您想要的部分。但通常情况下,open就足够了。
无论哪种方式,您都可以使用sin来代替sys.stdin.
或者,由于现在这是一个非常好的TextIOWrapper(假设您open在文本模式下编辑),因此替换是sys.stdin安全且合理的:
sys.stdin = sin\nRun Code Online (Sandbox Code Playgroud)\n\n\xe2\x80\xa6 和现在input等,将继续工作 \xe2\x80\x94 并将按照您希望的方式工作。