字典上的json.dumps带有密钥字节 [英] json.dumps on dictionary with bytes for keys

查看:90
本文介绍了字典上的json.dumps带有密钥字节的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试使用json.dumps()将字节类型为键的字典对象转换为json.事先不知道字典对象的格式.在使用json.dumps(

Trying to convert dictionary object with keys of type bytes to json using json.dumps(). Format of dictionary object is not known beforehand. Have found solution for arrays or dictionaries with byte values when using json.dumps (Convert bytes embedded in list (or dict) to str for use with json.dumps) but have not found one for byte keys.

import json

class BytesDump(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, bytes):
            return obj.decode()
        return json.JSONEncoder.default(self, obj)

foo = {'name': b'bob', 'age': 33, 'attributes': {'hair': b'brown', 'arms': 2}}
bar = {b'name': b'bob', b'age': 33, b'attributes': {b'hair': b'brown', b'arms': 2}}

print(json.dumps(foo, cls=BytesDump)) # this works
print(json.dumps(bar, cls=BytesDump)) # this doesn't work

上面的输出

{"name": "bob", "age": 33, "attributes": {"hair": "brown", "arms": 2}}
Traceback (most recent call last):
  File "./test.py", line 15, in <module>
    print(json.dumps(bar, cls=BytesDump))
  File "/usr/local/lib/python3.6/json/__init__.py", line 238, in dumps
    **kw).encode(obj)
  File "/usr/local/lib/python3.6/json/encoder.py", line 199, in encode
    chunks = self.iterencode(o, _one_shot=True)
  File "/usr/local/lib/python3.6/json/encoder.py", line 257, in iterencode
    return _iterencode(o, 0)
TypeError: keys must be a string

推荐答案

您可以对字典进行预处理,以将密钥(如果为字节)以递归方式转换为字符串

you could pre-process the dictionary to convert the keys as strings recursively if they're bytes

import json
# your dump code for values, unmodified
class BytesDump(json.JSONEncoder):
    def default(self, obj):
        if isinstance(obj, bytes):
            return obj.decode()
        return json.JSONEncoder.default(self, obj)

# recursive key as string conversion for byte keys
def keys_string(d):
    rval = {}
    if not isinstance(d, dict):
        if isinstance(d,(tuple,list,set)):
            v = [keys_string(x) for x in d]
            return v
        else:
            return d
    for k,v in d.items():
        if isinstance(k,bytes):
            k = k.decode()
        if isinstance(v,dict):
            v = keys_string(v)
        elif isinstance(v,(tuple,list,set)):
            v = [keys_string(x) for x in v]
        rval[k] = v
    return rval

print(json.dumps(keys_string(bar), cls=BytesDump))

具有:

bar = {b'name': b'bob', b'age': 33, b'attributes': {b'hair': b'brown', b'arms': 2},
b'other': [{b'hair': b'brown', b'arms': 2}]}

打印:

{"attributes": {"hair": "brown", "arms": 2}, "age": 33, "name": "bob", "other": [{"hair": "brown", "arms": 2}]}

这篇关于字典上的json.dumps带有密钥字节的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆