我有一个函数可以接收Python列表或字典,其中可能包含嵌套字节,需要在调用json.dumps之前将其转换为str。
该函数接收的数据结构不是众所周知的。它可以是一个列表,可以是嵌套结构,并且可以具有多种数据类型。如果只是将其传递为字节编码的字符串,则可以使用简单的encode()达到目的。
[n | n <- nodes, nodeId n == 0]
但是在这种情况下,我们收到的结构更加复杂(为简洁起见,我将回溯截断了)。
>>> foo = [b'dog', b'cat', b'cow']
>>> foo2 = [f.decode() for f in foo]
>>> foo2
['dog', 'cat', 'cow']`
>>> json.dumps(foo2)
'["dog", "cat", "cow"]'
想拥有一个可以接受任意Python结构(列表,字典等)并返回已解码所有字节的函数。
>>> foo = [[14, 3.5, b'Tom'], [18, -1.2, b'Larry'], [22, -1.7, b'Sue']]
>>> json.dumps(foo)
Traceback (most recent call last):
...
TypeError: Object of type 'bytes' is not JSON serializable
那么问题是,如何实现一个mydecoder函数,该函数可以接收具有不同类型的任意列表/字典(可能嵌套),并返回具有解码后的所有字节的相同结构?
答案 0 :(得分:2)
您可以将json.JSONEncoder
的子类传递给json.dumps
,该子类可以处理将字节字符串化的特殊情况。这将使您避免处理json编码器已经非常好的嵌套结构和边缘情况。您只需告诉它看到bytes
在这里,您只需要处理bytes
并让默认编码器完成其余工作即可:
import json
class BytesDump(json.JSONEncoder):
def default(self, obj):
if isinstance(obj, bytes): # deal with bytes
return obj.decode()
return json.JSONEncoder.default(self, obj) # everything else
foo = [{"key": b'value'}, [14, 3.5, b'Tom'], [18, -1.2, b'Larry'], [22, -1.7, 'Sue']]
json.dumps(foo, cls=BytesDump)
结果:
'[{"key": "value"}, [14, 3.5, "Tom"], [18, -1.2, "Larry"], [22, -1.7, "Sue"]]'
答案 1 :(得分:0)
抱歉,第一次来得有点慢。以下是转换和返回的方法:
import json
foo = [[14, 3.5, b'Tom'], [18, -1.2, b'Larry'], [22, -1.7, b'Sue']]
print(foo)
# to save
foo = [[i, j, k.decode("utf-8") ] for i, j, k in foo]
json_str = json.dumps(foo)
# to reload
foo = json.loads(json_str)
foo = [[i, j, bytes(k, 'utf-8')] for i, j, k in foo]
print(foo)