读取文件时不转换换行符

2024-02-07

我正在读取一个文本文件:

f = open('data.txt')
data = f.read()

然而换行符data当文件包含 CRLF ('\r\n') 时,变量被标准化为 LF ('\n')。

如何指示 Python 按原样读取文件?


在 Python 2.x 中:

f = open('data.txt', 'rb')

As the docs http://docs.python.org/2/library/functions.html#open say:

默认情况下是使用文本模式,该模式可以在写入时将“\n”字符转换为特定于平台的表示形式,并在读取时将其转换回来。因此,当打开二进制文件时,您应该附加'b'模式值以二进制模式打开文件,这将提高可移植性。 (附加'b'即使在不以不同方式处理二进制文件和文本文件的系统上(它充当文档)也很有用。)

在 Python 3.x 中,有三种选择:

f1 = open('data.txt', 'rb')

这将使换行符保持不变,但也会返回bytes代替str,你必须明确地decode自己进行 Unicode。 (当然,如果您想要 Unicode,2.x 版本也返回必须手动解码的字节,但在 2.x 中,这就是str对象是;在 3.x 中str是统一码。)

f2 = open('data.txt', 'r', newline='')

这将返回str,并保留换行符不翻译。然而,与 2.x 等效版本不同的是,readline和朋友会招待'\r\n'作为换行符,而不是后跟换行符的常规字符。通常这并不重要,但如果确实如此,请记住这一点。

f3 = open('data.txt', 'rb', encoding=locale.getpreferredencoding(False))

这与 2.x 代码处理换行符的方式完全相同,并返回str如果您只使用所有默认值,则使用相同的编码……但它在当前的 3.x 中不再有效。

从流中读取输入时,如果换行符为 None,则启用通用换行符模式。输入中的行可以以“\n”、“\r”或“\r\n”结尾,这些行在返回给调用者之前会被转换为“\n”。如果是 '',则启用通用换行模式,但行结尾会以未翻译的形式返回给调用者。

您需要指定显式编码的原因f3以二进制模式打开文件意味着默认的“decode withlocale.getpreferredencoding(False)” 到 “不解码,并返回原始数据bytes代替str”。再次,从the docs http://docs.python.org/3/library/functions.html#open:

在文本模式下,如果未指定编码,则使用的编码取决于平台:调用 locale.getpreferredencoding(False) 来获取当前区域设置编码。 (对于读取和写入原始字节,请使用二进制模式并保留未指定的编码。)

However:

'encoding' ...只能在文本模式下使用。

并且,至少从 3.3 开始,这是强制执行的;如果你尝试使用二进制模式,你会得到ValueError: binary mode doesn't take an encoding argument.

那么,如果您想编写同时适用于 2.x 和 3.x 的代码,您会使用什么?如果您想经营bytes, 明显地f and f1are the same. But if you want to deal instr, as appropriate for each version, the simplest answer is to write different code for each, probablyfandf2`,分别。如果这种情况经常出现,请考虑编写任一包装函数:

if sys.version_info >= (3, 0):
    def crlf_open(path, mode):
        return open(path, mode, newline='')
else:
    def crlf_open(path, mode):
        return open(path, mode+'b')

编写多版本代码时要注意的另一件事是,如果您不编写区域设置感知代码,locale.getpreferredencoding(False)在 3.x 中几乎总是返回一些合理的东西,但它通常只会返回'US-ASCII'在 2.x 中。使用locale.getpreferredencoding(True)从技术上讲是不正确的,但如果您不想考虑编码,则可能更可能是您真正想要的。 (尝试在 2.x 和 3.x 解释器中以两种方式调用它以了解原因,或者阅读文档。)

当然,如果您确实知道文件的编码,那总是比猜测要好。

无论哪种情况,'r'意思是“只读”。如果不指定模式,则默认为'r',所以相当于默认的二进制模式是'rb'.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

读取文件时不转换换行符 的相关文章

随机推荐