json.load 加载带有拉丁字符的文件时出错

Posted

技术标签:

【中文标题】json.load 加载带有拉丁字符的文件时出错【英文标题】:json.load gives error when loading a file with latin character 【发布时间】:2015-10-08 22:46:27 【问题描述】:

我正在做一个 python 项目,我对整个 utf-8/latin-1 编码/解码主题感到很困惑。

我的 linux 系统是一个 Openshift 免费帐户。

我正在尝试加载一个包含 json 数据对象的文件。该对象有一个包含拉丁字符的条目。

test.json:

 
 "name" : "Corazón"
 

当我在我的 Windows 系统上加载它时,我没有收到错误,但是 json.load 之后的结果是:

Windows 输出:

科拉桑

Openshift Linux 系统回溯

data = json.load(data_file, encoding='utf-8')
 File "/opt/rh/python33/root/usr/lib64/python3.3/json/__init__.py", line 271, in load
return loads(fp.read(),
 File "/opt/rh/python33/root/usr/lib64/python3.3/encodings/ascii.py", line 26, in decode
return codecs.ascii_decode(input, self.errors)[0]
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 18: ordinal not in range(128)

我的代码是:

import json

with open("test.json") as data_file:
    data = json.load(data_file, encoding='utf-8')

print(data['name'])

我尝试了不同的编码('utf-8'、'ascii'、'latin-1'),它们都给了我相同的结果。我显然在这里遗漏了一些东西。另外,如您所见,我从 windows 和 linux python 得到不同的结果。

我应该如何配置 json.load 以便它可以在 Windows 和 linux python 系统上正确加载文件?

更新 1

我进行了更多测试。 “test.json”文件是 utf-8 编码的,仍然给我上述结果。当我将文件编码为 ISO 8859-1 时,Windows 输出是正确的,但 linux out 仍然会导致错误。

我什至从这个 SO 问题中剪切并粘贴了 test.json 文件,以运行我的测试以与其他人在同一页面上。

更新 2

如果我将 test.json 文件转换为“Windows-1252”格式,则 Windows 输出是正确的。 linux盒子仍然会导致同样的错误。我不确定为什么文件被转换为 utf-8 时 windows 框不起作用。

【问题讨论】:

在我的 Linux 系统上使用此代码可以正常工作。也许尝试重写文件的那部分? print data['name'] 给了我 Corazón 我的生产开发系统是一个 Openshift 免费帐户。我想知道这是否与它有关? 为什么在我的 Windows 系统上还是不正确? 您是否使用 UTF-8 编码保存该 JSON 文件?您确定加载的对象是错误的,还是试图打印该对象? 查看我更新的问题以及其他答案中的 cmets。它现在可以在 Windows 上运行,但不能在 Openshift linux 上运行。 【参考方案1】:

在 Python 3 中,字符编码/解码由文件对象本身处理。在open() 调用中指定编码:

import json
with open("test.json", encoding='utf-8') as data_file:                           
    data = json.load(data_file)

print(data['name'])

它将在两个平台上正确加载文件,如果文件被正确编码为 UTF-8。

它绝对不会引发您显示的UnicodeDecodeError 错误,因为它没有使用ascii 编解码器。

如果您输出到控制台代码页必须包含您正在打印的所有字符,否则print() 将引发UnicodeEncodeError 错误。

我建议您不要回退到ISO 8859-1 编解码器。这些编解码器应被视为互联网上的传统编解码器。坚持使用 UTF-8 将为您省去在处理不同语言的名称(和其他文本)方面的许多其他麻烦。

【讨论】:

你只是复制了他的问题代码,对他不起作用,问题是为什么? @BigOldTree 我在上面指出了这一点:他的问题代码是正确的。但我不认为错误实际上来自该代码(因为他还发布了一个涉及“ascii”编解码器的 UnicodeDecodeError)。 它仍然不适合我。我用新信息更新了我的问题。 @thanks roeland。我实际上尝试将 'encoding='utf-8') 放在 json.load 参数中,但它不起作用。我在实际的“开放”声明中错过了它。再次感谢。我仍然很困惑为什么它可以在 windows 而不是 linux 上运行,但我很高兴 :)

以上是关于json.load 加载带有拉丁字符的文件时出错的主要内容,如果未能解决你的问题,请参考以下文章

Python使用json加载解析带有两个json对象列表的文件

为啥在replit中删除列表时json会出错

带有重音/拉丁字符的 JSON 请求

json

带有非拉丁字符的 Javascript slug 函数

带有多字节 UTF-8 文件名的 PHP basename() 和 pathinfo()