使用 JSON 保存 Python 元组

2022-01-19 00:00:00 python json tuples

问题描述

我对此还有些陌生,所以我可能不知道所有事物的常规术语:

I'm still a little new to this, so I might not know all the conventional terms for things:

使用 JSON 编码时是否可以保留 Python 元组?现在 json.loads(json.dumps(tuple)) 给了我一个列表.我不想将我的元组转换为列表,但我想使用 JSON.那么,有什么选择吗?

Is it possible to preserve Python tuples when encoding with JSON? Right now json.loads(json.dumps(tuple)) gives me a list back. I don't want to convert my tuples to lists, but I want to use JSON. So, are there options?

原因:我正在创建一个使用多维数组的应用程序,并不总是相同的形状.我有一些使用递归来探测数组并将端点转换为字符串或整数的类方法.我最近意识到(基于我的递归工作方式)我可以使用元组来防止对数组进行更深层次的递归搜索(Python rawks).在我确信我不需要深入探究我的数据结构的情况下,这可能会派上用场.

The reason why: I'm creating an app that uses multi-dimensional arrays, not always the same shape. I've got some class methods that use recursion to probe the arrays and cast the endpoints as a string or int. I recently realized that (based on how my recursion works) I can use tuples to prevent deeper recursive searching of arrays (Python rawks). This could come in handy in situations where I know I for sure I won't need to be probing any deeper into my data structures.


解决方案

你可以写一个高度专业化的encoder和decoder hook:

You can write a highly-specialzed encoder and a decoder hook:

import json

class MultiDimensionalArrayEncoder(json.JSONEncoder):
    def encode(self, obj):
        def hint_tuples(item):
            if isinstance(item, tuple):
                return {'__tuple__': True, 'items': item}
            if isinstance(item, list):
                return [hint_tuples(e) for e in item]
            if isinstance(item, dict):
                return {key: hint_tuples(value) for key, value in item.items()}
            else:
                return item

        return super(MultiDimensionalArrayEncoder, self).encode(hint_tuples(obj))

def hinted_tuple_hook(obj):
    if '__tuple__' in obj:
        return tuple(obj['items'])
    else:
        return obj


enc = MultiDimensionalArrayEncoder()
jsonstring =  enc.encode([1, 2, (3, 4), [5, 6, (7, 8)]])

print jsonstring

# [1, 2, {"items": [3, 4], "__tuple__": true}, [5, 6, {"items": [7, 8], "__tuple__": true}]]

print json.loads(jsonstring, object_hook=hinted_tuple_hook)

# [1, 2, (3, 4), [5, 6, (7, 8)]]

相关文章