Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 在模式定义后注册post_加载挂钩?_Python_Serialization_Deserialization_Marshalling_Marshmallow - Fatal编程技术网

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