如何在Marshmallow Schema继承中链式调用钩子函数?
在Marshmallow Schema继承中实现钩子函数链式调用
你遇到的问题是因为子类重写了和父类同名的post_load装饰方法,Marshmallow默认只会执行子类的钩子,父类的被覆盖了。这里有两种靠谱的解决方式:
方法一:子类钩子中显式调用父类钩子
在子类的post_load方法里,先调用父类的同名方法处理数据,再执行子类自己的逻辑,保证父类钩子先执行、子类钩子后执行:
from marshmallow import Schema, fields, post_load class PersonSchema(Schema): name = fields.Str() @post_load def post_load(self, data, **_): data["name"] = data["name"].capitalize() return data class EmployeeSchema(PersonSchema): title = fields.Str() @post_load def post_load(self, data, **_): # 先调用父类钩子处理name字段 data = super().post_load(data, **_) # 再执行子类自己的逻辑处理title字段 data["title"] = data["title"].upper() return data result = EmployeeSchema().load({"name": "john", "title": "ceo"}) # 输出: {"name": "John", "title": "CEO"}
方法二:给钩子方法设置不同名称
Marshmallow会收集继承链中所有被@post_load装饰的方法,按父类到子类的顺序执行,只要方法名不重复就不会出现覆盖问题。给父类和子类的钩子方法起不同名字即可:
from marshmallow import Schema, fields, post_load class PersonSchema(Schema): name = fields.Str() @post_load def capitalize_name(self, data, **_): data["name"] = data["name"].capitalize() return data class EmployeeSchema(PersonSchema): title = fields.Str() @post_load def uppercase_title(self, data, **_): data["title"] = data["title"].upper() return data result = EmployeeSchema().load({"name": "john", "title": "ceo"}) # 输出: {"name": "John", "title": "CEO"}
两种方法都能实现钩子的链式执行:方法一适合需要灵活控制执行顺序的场景,方法二能避免方法名冲突,让代码结构更清晰。
内容的提问来源于stack exchange,提问作者renatodamas
相关产品推荐
相关产品推荐

