将Python namedtuple序列化为json

建议namedtuple使用保留的字段名称将a序列化为json

的建议方式是什么?

将a namedtuple序列化为json只会导致值被序列化,并且字段名称在转换中会丢失。我希望在json大小化时也保留这些字段,因此请执行以下操作:

class foobar(namedtuple('f', 'foo, bar')):

__slots__ = ()

def __iter__(self):

yield self._asdict()

上面的代码按照我的期望序列化为json,并且namedtuple在我使用的其他地方(属性访问等)中起作用,除了在迭代过程中出现非元组之类的结果外(对于我的用例来说这很好)。

在保留字段名称的情况下转换为json的“正确方法”是什么?

回答:

这非常棘手,因为这namedtuple()是一个工厂,该工厂返回从派生的新类型tuple。一种方法是让您的类也继承自UserDict.DictMixin,但tuple.__getitem__已经定义了,并且需要一个整数来表示元素的位置,而不是其属性的名称:

>>> f = foobar('a', 1)

>>> f[0]

'a'

从本质上讲,namedtuple非常适合JSON,因为它实际上是一种

,而字典中的键名存储在实例中。这可以防止您“往返”一个命名元组,例如,在没有其他信息的情况下,您无法将字典解码回一个命名元组,例如dict中的特定于应用程序的类型标记{'a':

1, '#_type': 'foobar'},这有点麻烦。

这不是理想的方法,但是 namedtuple

为字典,则另一种方法是将JSON编码器扩展或修改为特殊类型的这些类型。这是Python的子类化示例json.JSONEncoder。这解决了确保嵌套的命名元组正确转换为字典的问题:

from collections import namedtuple

from json import JSONEncoder

class MyEncoder(JSONEncoder):

def _iterencode(self, obj, markers=None):

if isinstance(obj, tuple) and hasattr(obj, '_asdict'):

gen = self._iterencode_dict(obj._asdict(), markers)

else:

gen = JSONEncoder._iterencode(self, obj, markers)

for chunk in gen:

yield chunk

class foobar(namedtuple('f', 'foo, bar')):

pass

enc = MyEncoder()

for obj in (foobar('a', 1), ('a', 1), {'outer': foobar('x', 'y')}):

print enc.encode(obj)

{"foo": "a", "bar": 1}

["a", 1]

{"outer": {"foo": "x", "bar": "y"}}

以上是 将Python namedtuple序列化为json 的全部内容, 来源链接: utcz.com/qa/409069.html

回到顶部