Let us say I have a custom data structure comprising of primitive dicts. I need to serialize this using JSON. My structure is as follows:
假设我有一个自定义的数据结构,由原始的命令组成。我需要使用JSON对其进行序列化。我的结构如下:
path_list_dict = {(node1, node2 .. nodeN): (float1, float2, float3)}
So this is keyed with a tuple and the value is a tuple of three values. Each node element in the key is a custom class object with a _str_ method written for it. The wrapper dict which identifies each dict entry in path_list_dict with a key is as follows:
这是一个元组键值是三个值的元组。键中的每个节点元素都是一个自定义类对象,并为此编写了_str_方法。在path_list_dict词中使用一个键标识每个dict条目的包装器敕令如下:
path_options_dict = {‘Path1’: {(node1, node2 .. nodeN): (float1, float2, float3)}, ‘Path2’: {(nodeA1, nodeA2 .. nodeAN): (floatA1, floatA2, floatA3)} }
and so on.
等等。
When I try to serialize this using JSON, of course I run into a TypeError because the inner dict has tuples as keys and values and a dict needs to have keys as strings to be serialized. This can be easily taken care of for me by inserting into the dict as the str(tuple) representation instead of just the native tuple.
当我尝试使用JSON进行序列化时,当然会遇到一个TypeError,因为内部的dict具有元组作为键和值,而一个dict必须具有作为字符串的键作为要序列化的字符串。这可以通过将str(tuple)表示插入到dict类型中(而不仅仅是本机tuple)来轻松地处理。
What I am concerned about is that when I receive it and unpack the values, I am going to have all strings at the receiving end. The key tuple of the inner dict that consists of custom class elements is now represented as a str. Will I be able to recover the embedded data? Or is these some other way to do this better?
我关心的是,当我接收它并解压值时,我将在接收端拥有所有的字符串。由自定义类元素组成的内部命令的关键元组现在被表示为一个str。我能恢复嵌入的数据吗?或者有其他更好的方法吗?
For more clarity, I am using this JSON tutorial as reference.
为了更清晰,我使用这个JSON教程作为参考。
1 个解决方案
#1
1
You have several options:
你有几个选择:
-
Serialize with a custom key prefix that you can pick out and unserialize again:
使用一个自定义的键前缀进行序列化,您可以再次选择和取消序列化:
tuple_key = '__tuple__({})'.format(','.join(key))
would produce
'__tuple__(node1,node2,nodeN)'
as a key, which you could parse back into a tuple on the other side:将生成“__tuple__(node1,node2,nodeN)”作为键,您可以将其解析为另一端的元组:
if key.startswith('__tuple__('): key = tuple(key[10:-1].split(','))
Demo:
演示:
>>> key = ('node1', 'node2', 'node3') >>> '__tuple__({})'.format(','.join(key)) '__tuple__(node1,node2,node3)' >>> mapped_key = '__tuple__({})'.format(','.join(key)) >>> tuple(mapped_key[10:-1].split(',')) ('node1', 'node2', 'node3')
-
Don't use dictionaries, use a list of lists:
不要使用字典,使用列表列表:
{'Path': [[[node1, node2 .. nodeN], [float1, float2, float3]], [...]]}
You can build such a list simply from the
dict.items()
result:您可以简单地从dict.items()结果构建这样的列表:
>>> json.dumps({(1, 2, 3): ('foo', 'bar')}.items()) '[[[1, 2, 3], ["foo", "bar"]]]'
and when decoding, feed the whole thing back into
dict()
while mapping each key-value list to tuples:解码时,将整个内容返回到dict()中,同时将每个键值列表映射到元组:
>>> dict(map(tuple, kv) for kv in json.loads('[[[1, 2, 3], ["foo", "bar"]]]')) {(1, 2, 3): (u'foo', u'bar')}
The latter approach is more suitable for custom classes as well, as the JSONEncoder.default()
method will still be handed these custom objects for you to serialize back to a suitable dictionary object, which gives means that a suitable object_hook
passed to JSONDecoder()
a chance to return fully deserialized custom objects again for those.
后一种方法更适合定制类,随着JSONEncoder.default()方法仍将给这些为你定制对象序列化到一个合适的字典对象,这使意味着一个合适object_hook传递给JSONDecoder()返回的机会再次对那些完全反序列化自定义对象。
#1
1
You have several options:
你有几个选择:
-
Serialize with a custom key prefix that you can pick out and unserialize again:
使用一个自定义的键前缀进行序列化,您可以再次选择和取消序列化:
tuple_key = '__tuple__({})'.format(','.join(key))
would produce
'__tuple__(node1,node2,nodeN)'
as a key, which you could parse back into a tuple on the other side:将生成“__tuple__(node1,node2,nodeN)”作为键,您可以将其解析为另一端的元组:
if key.startswith('__tuple__('): key = tuple(key[10:-1].split(','))
Demo:
演示:
>>> key = ('node1', 'node2', 'node3') >>> '__tuple__({})'.format(','.join(key)) '__tuple__(node1,node2,node3)' >>> mapped_key = '__tuple__({})'.format(','.join(key)) >>> tuple(mapped_key[10:-1].split(',')) ('node1', 'node2', 'node3')
-
Don't use dictionaries, use a list of lists:
不要使用字典,使用列表列表:
{'Path': [[[node1, node2 .. nodeN], [float1, float2, float3]], [...]]}
You can build such a list simply from the
dict.items()
result:您可以简单地从dict.items()结果构建这样的列表:
>>> json.dumps({(1, 2, 3): ('foo', 'bar')}.items()) '[[[1, 2, 3], ["foo", "bar"]]]'
and when decoding, feed the whole thing back into
dict()
while mapping each key-value list to tuples:解码时,将整个内容返回到dict()中,同时将每个键值列表映射到元组:
>>> dict(map(tuple, kv) for kv in json.loads('[[[1, 2, 3], ["foo", "bar"]]]')) {(1, 2, 3): (u'foo', u'bar')}
The latter approach is more suitable for custom classes as well, as the JSONEncoder.default()
method will still be handed these custom objects for you to serialize back to a suitable dictionary object, which gives means that a suitable object_hook
passed to JSONDecoder()
a chance to return fully deserialized custom objects again for those.
后一种方法更适合定制类,随着JSONEncoder.default()方法仍将给这些为你定制对象序列化到一个合适的字典对象,这使意味着一个合适object_hook传递给JSONDecoder()返回的机会再次对那些完全反序列化自定义对象。