繁体   English   中英

将嵌入在列表(或字典)中的字节转换为str以与json.dumps一起使用

[英]Convert bytes embedded in list (or dict) to str for use with json.dumps

我有一个函数可以接收Python列表或字典,其中可能包含嵌套字节,需要在调用json.dumps之前将其转换为str。

该功能接收的数据结构不是众所周知的。 它可以是一个列表,可以是嵌套结构,并且可以具有多种数据类型。 如果只是传递一个字节编码的字符串,则简单的decode()就可以解决问题。

>>> foo = [b'dog', b'cat', b'cow']
>>> foo2 = [f.decode() for f in foo]
>>> foo2
['dog', 'cat', 'cow']`
>>> json.dumps(foo2)
'["dog", "cat", "cow"]'

但在这种情况下,我们会收到更复杂的结构(为简洁起见,我将回溯截断了)。

>>> 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

希望有一个函数可以接受任意Python结构(列表,字典等),并在解码所有字节后返回相同的函数。

>>> foo = [[14, 3.5, b'Tom'], [18, -1.2, b'Larry'], [22, -1.7, b'Sue']]
>>> foo2 = mydecoder(foo)
>>> foo2
[[14, 3.5, 'Tom'], [18, -1.2, 'Larry'], [22, -1.7, 'Sue']]
>>> json.dumps(foo2)
'[[14, 3.5, "Tom"], [18, -1.2, "Larry"], [22, -1.7, "Sue"]]'

那么问题是如何实现mydecoder函数,该函数可以接受具有不同类型的任意列表/字典(可能嵌套),并返回相同的结构并解码所有字节?

您可以将json.JSONEncoder的子类json.JSONEncoderjson.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"]]'

抱歉,第一次快了一点。 以下是转换和返回的方法:

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)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM