更改python3中stdin/stdout的打开方式

2024-04-27 02:18:12 发布

您现在位置:Python中文网/ 问答频道 /正文

在最近的Python3.x中,open的默认行为是以universal newlines模式(newline=None)打开文件,这意味着如果我打开这样的文件:

f = open("file.txt")

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

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

更一般地说,Python中是否有类似于Perl的binmode的东西,允许将sys.stdin/写改为{}的工作方式?在

我只想说清楚,我知道我自己可以做CRLF→LF转换。这不是这个问题的重点。在


Tags: 文件nonereadlinestdinsysnewline模式open
2条回答

没有办法完全替代Python在sys.stdinsys.stdout中包装stdin和stdout管道的方式。(有一些受限的控件,比如the ^{} option`,但仅此而已。)

然而,你要求的是很多其他的东西,所有这些都是可能的,其中一些可能是你想要的。在


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

sys.stdin.buffer
sys.stdin.buffer.raw
sys.stdin.fileno()

通常,这就是你所需要的。您不想实际替换sys.stdin = sys.stdin.buffer。这将破坏inputfileinput模块,谁知道还有什么东西期望{}成为文本文件。但是您可以使用sys.stdin.buffer而不是sys.stdin,它大致相当于我认为您从perl的binmode中寻找的内容。在


如果你想要一个TextIOWrapper在同一个底层文件中包装不同的选项,你也可以这样做。在

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

^{pr2}$

对于不那么简单的情况,您可能需要阅读TextIOWrapper文档(以及BufferedReader和{}模块中的其他类型),并以您想要的方式准确地包装您想要的部分。但通常,open就足够了。在

无论哪种方式,您都可以使用sin来代替{}。在

或者,既然现在这个是一个非常好的TextIOWrapper(假设您是在文本模式下open),那么替换{}是安全和合理的:

sys.stdin = sin

…现在,input等将继续工作,并将按照您希望的方式工作。在

这可以通过以下方式解决:

sys.stdin = io.TextIOWrapper(sys.stdin.buffer)

这会导致sys.stdin的行为就像使用带有默认参数的open打开的一样(包括newline=None)。TextIOWrapper的构造函数采用与open相同的参数,因此我们还可以执行以下操作:

^{pr2}$

等等

因此,我们有一种方法可以影响stdin/stdout的打开方式,类似于Perl的binmode(即binmode FILEHANDLE, LAYERS版本)。在

感谢@abarnert对TextIOWrapper的评论。在

相关问题 更多 >