尝试使用json.dumps()将字节类型为键的字典对象转换为json。事先不知道字典对象的格式。使用json.dumps(Convert bytes embedded in list (or dict) to str for use with json.dumps)时,找到了具有字节值的数组或字典的解决方案,但未找到用于字节键的解决方案。
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
答案 0 :(得分:1)
您可以对字典进行预处理,以将键(如果为字节)以递归方式转换为字符串
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 = {}
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}]}
答案 1 :(得分:1)
看起来您需要使用递归实用程序功能:
import json
def decode_dict(d):
result = {}
for key, value in d.items():
if isinstance(key, bytes):
key = key.decode()
if isinstance(value, bytes):
value = value.decode()
elif isinstance(value, dict):
value = decode_dict(value)
result.update({key: value})
return result
bar = {b'name': b'bob', b'age': 33, b'attributes': {b'hair': b'brown', b'arms': 2}}
print(json.dumps(decode_dict(bar)))
输出:
{"name": "bob", "age": 33, "attributes": {"hair": "brown", "arms": 2}}