带有棉花糖的顶级列表和字典

Top level lists and dictionaries with marshmallow

是否可以为顶级列表(例如 obj = ['John', 'Bill', 'Jack'])或字典(例如 obj = {'user1': 123, 'user2': 456, 'user3': 789} - 键是任意的)定义棉花糖架构?

顶级字典是正常情况。要接受任意键,请参阅 unknown=INCLUDE,但是您没有验证,这与使用 Dict 字段时不同。

对此的解决方案是为未知字段定义一个默认字段,或者扩展字段以使其充当模式。前者已经被建议(我相信是我提出的)并且应该不难实现,但没有人花时间研究它。后者是由 Jared 建议的,将是一个重要的重构。没有人在研究它。

顶级字典列表是使用 many=True 模式的正常情况。任何东西的顶级列表都还无法实现。这将适用于上述重构。

作为 Jérôme ,参数 many=True.

支持模式列表

对于键数未知的 dict(但可能是已知的 key/value 类型),Dict 字段中的一切都已准备就绪。做一个小的subclass可以给人一种处理正常Schema的感觉(至少w.r.t。dumpload),例如:

import typing
from marshmallow import fields
from marshmallow_dataclass import dataclass


class PoorMansDictSchema(fields.Dict):
    @staticmethod
    def _get_obj(obj, _attr, _default):
        return obj

    def dump(self, obj: typing.Any):
        return self.serialize('', obj, accessor=self._get_obj)

    def load(self, data: typing.Mapping[str, typing.Any]):
        return self.deserialize(data)


@dataclass
class Record:
    name: str
    value: float


dict_schema = PoorMansDictSchema(keys=fields.Str(),
                                 values=fields.Nested(Record.Schema))

records = {'a': Record('a', 1.0), 'b': Record('b', 2.0)}
print(records)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}
serialized_records = dict_schema.dump(records)
print(serialized_records)
# {'a': {'name': 'a', 'value': 1.0}, 'b': {'name': 'b', 'value': 2.0}}
records_back = dict_schema.load(serialized_records)
print(records_back)
# {'a': Record(name='a', value=1.0), 'b': Record(name='b', value=2.0)}

我在示例中使用了 marshmallow-dataclass 以使其更简洁(从 class 推断出 Schema)。显然,PoorMansDictSchemadump/load 不支持 manypartialunknown 覆盖 Schema 相关特权,但仍可在嵌套架构中定义这些特权。