具有多态性的 Python 棉花糖树结构 [英] Python marshmallow tree structure with polymorphism

查看:62
本文介绍了具有多态性的 Python 棉花糖树结构的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下树结构代码:

class Node:
    def __init__(self, node_id: str):
        self.node_id = node_id
        self.children = []

    def add_child(self, node: 'Node'):
        if isinstance(node, Node):
            self.children.append(node)


class ValueNode(Node):
    def __init__(self, value: bool, **kwargs):
        Node.__init__(self, **kwargs)
        self.value = value


class LogicNode(Node):
    def __init__(self, logic_operator: str, **kwargs):
        Node.__init__(self, **kwargs)
        self.logic_operator = logic_operator


a = Node("a")
b = LogicNode("or", node_id="b")
c = ValueNode(True, node_id="c")
d = ValueNode(False, node_id="d")

b.add_child(c)
b.add_child(d)
a.add_child(b)

如何在保持正确的类型和树结构的同时将对象 a 序列化为 json 并再次返回到 python 对象?

How can I serialize object a into json and back again into a python object while keeping the correct types and tree structure?

我的尝试:

我正在尝试将此树结构序列化为 json,以便通过 API 发送到 ui.我发现了棉花糖,但不幸的是,我无法弄清楚如何去做.我有这个作为模式 atm.

I am trying to serialize this tree structure into json in order to send to an ui through an API. I found about marshmallow but unfortunately, I am unable to figure out how to do it. I have this as schemas atm.

class NodeSchema(Schema):
    node_id = fields.String()
    children = fields.Nested('self', many=True)

    @post_load
    def load(self, data):
        return Node(**data)


class ValueNodeSchema(NodeSchema):
    value = fields.Boolean()


class LogicNodeSchema(NodeSchema):
    logic_operator = fields.String()

这里的问题是,当序列化为 json 时,即使子节点是逻辑节点或值节点(有点预期),也只有节点的属性存在.我发现了关于 marshmallow-oneofschema here github 但我无法使用它,因为它我必须更换:

Here the problem is that when serialized into json only the attributes of Node are there even if the children are logical node or value node (kinda expected). I found about marshmallow-oneofschema here github but I am unable to use it because with it I have to replace:

# In NodeSchema
children = fields.Nested('self', many=True)

与:

class SomeNodeSchema(OneOfSchema):
    type_schemas = {
        'node': NodeSchema,
        'logic_node': LogicNodeSchema,
        'value_node': ValueNodeSchema,
    }

    def get_obj_type(self, obj):
        if isinstance(obj, LogicNode):
            return 'logic_node'
        if isinstance(obj, ValueNode):
            return 'value_node'
        elif isinstance(obj, Node):
            return 'node'

# In NodeSchema
children = fields.Nested(SomeNodeSchema, many=True)

但这会导致循环导入,从而无法实现.

but this leads to a circular import which makes it impossible.

推荐答案

我发现了关于 marshmallow-oneofschema

I found about marshmallow-oneofschema

虽然没有集成到核心,但我认为 marshmallow-oneofschema 是实现多态的推荐方式.

Although not integrated to the core, I think marshmallow-oneofschema is the recommended way to do polymorphism.

这会导致循环导入

您可以将名称作为字符串传递以解决循环导入问题.

You may pass the name as string to solve the circular import issue.

    children = fields.Nested('SomeNodeSchema', many=True)

这篇关于具有多态性的 Python 棉花糖树结构的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆