You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Marshmallow Schema中将对象属性分组到新字典

解决方案:用Marshmallow将平级属性打包到新字典中

这个问题我之前也碰到过!Marshmallow默认只会序列化Schema里定义且原对象存在对应键的字段,所以原数据里没有stats键的话,Nested(StatsSchema)自然不会输出。要把平级的population和rating打包进新的stats字典,有两种简单的实现方式:

方法一:使用Method字段自定义序列化逻辑

通过fields.Method指定一个方法,手动从原对象中提取需要的属性并组装成stats字典:

from marshmallow import Schema, fields
import json

class StatsSchema(Schema):
    population = fields.Int()
    rating = fields.Int()

class AnimalSchema(Schema):
    name = fields.Str()
    features = fields.List(fields.Str())
    # 用Method字段自定义stats的序列化逻辑
    stats = fields.Method("extract_stats")

    def extract_stats(self, obj):
        # 从原对象中取出population和rating,组装成目标字典
        return {
            "population": obj.get("population"),
            "rating": obj.get("rating")
        }

# 测试数据
dog = {
    'name':'dog',
    'features': ['tongue', 'wet nose'],
    'population': 200,
    'rating': 10
}

animal_schema = AnimalSchema()
data, errors = animal_schema.dump(dog)
print(json.dumps(data, indent=2))

运行后输出:

{
  "features": [
    "tongue",
    "wet nose"
  ],
  "name": "dog",
  "stats": {
    "population": 200,
    "rating": 10
  }
}

方法二:使用post_dump装饰器后处理

如果你希望先序列化所有字段,再调整结构,可以用post_dump装饰器在序列化完成后将平级属性打包进stats:

from marshmallow import Schema, fields, post_dump
import json

class AnimalSchema(Schema):
    name = fields.Str()
    features = fields.List(fields.Str())
    # 先把population和rating作为普通字段包含进来
    population = fields.Int()
    rating = fields.Int()

    @post_dump
    def wrap_in_stats(self, data, **kwargs):
        # 提取并移除平级的属性,打包进stats字典
        stats = {
            "population": data.pop("population"),
            "rating": data.pop("rating")
        }
        data["stats"] = stats
        return data

# 测试数据
dog = {
    'name':'dog',
    'features': ['tongue', 'wet nose'],
    'population': 200,
    'rating': 10
}

animal_schema = AnimalSchema()
data, errors = animal_schema.dump(dog)
print(json.dumps(data, indent=2))

这种方式的好处是可以在序列化后统一调整数据结构,适合需要多字段批量处理的场景。

补充说明

如果担心原数据中population或rating不存在的情况,可以在方法中添加默认值,比如obj.get("population", 0),避免出现None值。

内容的提问来源于stack exchange,提问作者wbruntra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:43:21