Python 在模式定义后注册post_加载挂钩?
我正在尝试实现一个模式,其中对象类在模式定义时是未知的。我假设我可以在运行时注册Python 在模式定义后注册post_加载挂钩?,python,serialization,deserialization,marshalling,marshmallow,Python,Serialization,Deserialization,Marshalling,Marshmallow,我正在尝试实现一个模式,其中对象类在模式定义时是未知的。我假设我可以在运行时注册post\u load函数,但是post\u load只对类方法有效 看来我可以通过以下两种方式来实现: 更新Schema.\u手动或通过 以某种方式在运行时创建绑定方法并注册它 由于这两个选项都有点老套,有没有一种官方方法可以达到相同的结果?如果其他人需要,我已经用一个自定义元类解决了这个问题,该类预先注册了一个post_load函数,该函数的实际实现可以在运行时提供: 从类型导入方法类型 从棉花糖导入模式,p
post\u load
函数,但是post\u load
只对类方法有效
看来我可以通过以下两种方式来实现:
- 更新
Schema.\u手动或通过
- 以某种方式在运行时创建绑定方法并注册它
由于这两个选项都有点老套,有没有一种官方方法可以达到相同的结果?如果其他人需要,我已经用一个自定义元类解决了这个问题,该类预先注册了一个post_load函数,该函数的实际实现可以在运行时提供:
从类型导入方法类型
从棉花糖导入模式,post_加载
从marshmallow.schema导入SchemaMeta
类MyCustomSchemaMeta(SchemaMeta):
定义初始值(cls、*ARG、**kwargs):
super()
def make_obj(*args,**kwargs):
引发未实现的错误
#此post_load调用将方法注册到架构中
cls.make_obj=后加载(make_obj)
类MyCustomSchema(模式,元类=MyCustomSchemaMeta):
“”“这是我的架构继承的基类。”“”
#make_obj的实际实现(以及反序列化到的类)
#现在可以在运行时提供。post_load调用不会影响架构
#不再使用,但在方法上设置一些参数。
MyCustomSchema.make_obj=MethodType(
post_加载(lambda self,数据:MyClass(**数据)),MyCustomSchema
)
我认为您不需要元类
使用只需要类的post load方法定义基本架构
class CustomSchema(Schema):
@post_load
def make_obj(self, data):
return self.OBJ_CLS(**data)
如果在导入时已知该类(而不是您的用例),这允许您通过提供该类来分解实例化。已经很好了
class PetSchema(CustomSchema):
OBJ_CLS = Pet
如果在导入时不知道该类,则可以在导入后提供该类
class PetSchema(CustomSchema):
pass
PetSchema.OBJ_CLS = Pet
如果在实例化之前需要更多的处理,那么您可以在任何类中重写make_obj
,如您在答案中所示
class PetSchema(CustomSchema):
def make_obj(self, data):
data = my_func(data)
return Pet(**data)
更一般地说,这种机制允许您在基本模式中定义挂钩。这是克服棉花糖当前限制的一个好方法:多个
post\u load
方法可以以任何顺序执行。在基类中为每个处理步骤定义一个带有钩子的post_load
方法。(这个人为的例子并不能真正说明这一点。)
class CustomSchema(Schema):
@post_load
def post_load_steps(self, data):
data = self.post_load_step_1(data)
data = self.post_load_step_2(data)
data = self.post_load_step_3(data)
return data
def post_load_step_1(self, data):
return data
def post_load_step_2(self, data):
return data
def post_load_step_3(self, data):
return data