如何将 encoding='utf-8-sig' 与 json.loads() 一起使用?

how to use encoding='utf-8-sig' with json.loads()?

提问人:vinter5 提问时间:6/24/2023 最后编辑:vinter5 更新时间:6/24/2023 访问量:561

问:

我发现了一些关于这个问题的其他问题,但解决方案不起作用和/或我不理解它们。

代码是这样的:

file_data = {}
with open(path) as open_file:
    data = open_file.read()
try:
    file_data = json.loads(data)
except:
    try:
        file_data = json.loads(data, encoding='utf-8-sig')
    except:
        print("this gets printed")

正在读取的文件有点像这样,请注意度°标记,这可能是问题所在?

{ "name": "something", "temperature": "44°", "sensor": "model_xyz" }

文件在记事本++中显示为UTF-8-BOM

我得到的错误是:KeyError:“名称”

用 python 打印时的文件输出前面有 。

为什么这不起作用: json.loads(data, encoding='utf-8-sig') ?

尝试 encoding='utf-8-sig',似乎没有做任何事情,json.loads(data) 在文件中找不到任何东西。

python json utf-8

评论

0赞 tdelaney 6/24/2023
捕获和抑制错误使这更难解决。 是无效的 JSON。 是一个整数,但添加该度数符号会使其无效 - 因为为什么序列化协议会知道度数是什么?如果你把它变成一个字符串,那么你就会有一些有效的东西。因此,如果您显示的示例是 JSON 文件,那么无论写入什么都是错误的。"temperature": 44°44"44°"
0赞 vinter5 6/24/2023
对不起,这是一个错别字,它周围有“”
1赞 vinter5 6/24/2023
我想我通过添加 , encoding='utf-8-sig' 来修复它: with open(path, encoding='utf-8-sig') as open_file:
1赞 tdelaney 6/24/2023
JSON 本身不知道 utf-8-sig。它可以将几个字节放在文件的前面,以区分 UTF-8、UTF-16 和字节顺序。将编码放在打开调用中应该可以:',open(path, endoing=“utf-8-sig”) open_file: file_data = json.load(open_file)'

答:

2赞 Mark Tolonen 6/24/2023 #1

json.loadsjson.load 不采用编码参数。在打开文件进行读取和写入时应指定它。

根据 RFC 8259 - JavaScript 对象表示法 (JSON) 数据交换格式

8.1. 字符编码

在不属于封闭生态系统的系统之间交换的 JSON 文本必须使用 UTF-8 [RFC3629] 进行编码。

以前的 JSON 规范在传输 JSON 文本时不要求使用 UTF-8。但是,绝大多数基于 JSON 的软件实现都选择使用 UTF-8 编码,因为它是唯一实现互操作性的编码。

实现不得在网络传输的 JSON 文本的开头添加字节顺序标记 (U+FEFF)。为了实现互操作性,解析 JSON 文本的实现可能会忽略字节顺序标记的存在,而不是将其视为错误。

因此,要读取文件,请使用以下内容,“为了互操作性”,如果存在,它将删除字节顺序标记:

with open(filename, encoding='utf-8-sig') as f:
    data = json.load(f)

对于写作用途:

with open(filename, 'w', encoding='utf8') as f:
    data = json.dump(data, f)

如果您有 JSON 字节字符串(Python 对象),则默认解码为:bytesjson.loadsutf-8-sig

>>> import json
>>> data = '{"name": "马克"}'.encode('utf-8-sig')
>>> data
b'\xef\xbb\xbf{"name": "\xe9\xa9\xac\xe5\x85\x8b"}'
>>> json.loads(data)
{'name': '马克'}

但是,如果由于某种原因,您的 JSON 数据以另一种编码编码,请先对其进行解码:

>>> import json
>>> data = '{"name": "马克"}'.encode('chinese')
>>> data
b'{"name": "\xc2\xed\xbf\xcb"}'
>>> json.loads(data.decode('chinese'))
{'name': '马克'}