写入然后读取以 latin1 编码的文件中的字符串

Fra*_*eau 6 python io latin1

这里有 2 个代码示例,Python3:第一个使用 latin1 编码写入两个文件:

s='On écrit ça dans un fichier.'
with open('spam1.txt', 'w',encoding='ISO-8859-1') as f:
    print(s, file=f)
with open('spam2.txt', 'w',encoding='ISO-8859-1') as f:
    f.write(s)
Run Code Online (Sandbox Code Playgroud)

第二个读取具有相同编码的相同文件:

with open('spam1.txt', 'r',encoding='ISO-8859-1') as f:
    s1=f.read()
with open('spam2.txt', 'r',encoding='ISO-8859-1') as f:
    s2=f.read()
Run Code Online (Sandbox Code Playgroud)

现在,打印 s1 和 s2 我得到

On écrit ça dans un fichier.
Run Code Online (Sandbox Code Playgroud)

而不是最初的“On écrit ça dans un fichier”。

怎么了 ?我也尝试过 io.open 但我错过了一些东西。有趣的是,我对 Python2.7 及其 str.decode 方法没有这样的问题,现在它已经消失了......

有人可以帮助我吗?

Mar*_*ers 6

您的数据以 UTF-8 格式写出:

>>> 'On écrit ça dans un fichier.'.encode('utf8').decode('latin1')
'On écrit ça dans un fichier.'
Run Code Online (Sandbox Code Playgroud)

这要么意味着您没有写出 Latin-1 数据,要么您的源代码被保存为 UTF-8,但您声明了您的脚本(使用符合 PEP 263 的标头改为 Latin-1。

如果您使用以下标题保存 Python 脚本:

# -*- coding: latin-1 -*-
Run Code Online (Sandbox Code Playgroud)

但是您的文本编辑器使用 UTF-8 编码保存文件,然后是字符串文字:

s='On écrit ça dans un fichier.'
Run Code Online (Sandbox Code Playgroud)

也会以同样的方式被 Python 误解。将生成的 unicode 值作为 Latin-1 保存到磁盘,然后再次读取为 Latin-1 将保留错误。

要进行调试,请大家仔细看print(s.encode('unicode_escape'))第一个脚本。如果它看起来像:

b'On \\xc3\\xa9crit \\xc3\\xa7a dans un fichier.'
Run Code Online (Sandbox Code Playgroud)

那么您的源代码编码和 PEP-263 标头在如何解释源代码方面存在分歧。如果您的源代码被正确解码,则正确的输出是:

b'On \\xe9crit \\xe7a dans un fichier.'
Run Code Online (Sandbox Code Playgroud)

如果Spyder的是固执地忽略了PEP-263头和阅读源拉丁-1无论使用非ASCII字符和使用转义码,而不是躲避; 要么使用\uxxxxunicode 代码点:

s = 'On \u00e9crit \u007aa dans un fichier.'
Run Code Online (Sandbox Code Playgroud)

\xaa256 以下代码点的一字节转义码:

s = 'On \xe9crit \x7aa dans un fichier.'
Run Code Online (Sandbox Code Playgroud)