【问题标题】:Python marshmallow tree structure with polymorphism具有多态性的 Python 棉花糖树结构
【发布时间】:2019-03-10 22:08:36
【问题描述】:

我有以下代码用于树结构:

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 对象,同时保持正确的类型和树结构?

我尝试了什么:

我正在尝试将此树结构序列化为 json,以便通过 API 发送到 ui。我发现了棉花糖,但不幸的是,我不知道该怎么做。我有这个作为模式 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 时,即使子节点是逻辑节点或值节点(有点预期),也只有 Node 的属性存在。我发现了 marshmallow-oneofschema here github 但我无法使用它,因为我必须用它替换:

# 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)

但这会导致循环导入,这使得它不可能。

【问题讨论】:

  • 虽然没有集成到核心,但我认为marshmallow-oneofschema是推荐的方式。将名称作为字符串传递是否可以解决循环导入问题? children = fields.Nested('SomeNodeSchema', many=True)
  • 嗨@Jérôme,非常感谢您的回答。通过将类名作为字符串传递,它可以完美地工作。愚蠢的我不要尝试,即使'self'也是一个字符串:D。如果你愿意,你可以回答,我可以批准。干杯。
  • 太棒了。我将其编辑为答案。

标签: python serialization polymorphism marshmallow


【解决方案1】:

我发现了 marshmallow-oneofschema

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

这会导致循环导入

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

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

【讨论】:

    猜你喜欢
    • 2019-01-29
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 2018-09-08
    • 1970-01-01
    • 2018-09-19
    • 2017-02-02
    • 1970-01-01
    相关资源
    最近更新 更多