如何在colander中创建“类型无关”的SchemaNode

4 投票
2 回答
797 浏览
提问于 2025-04-18 03:50

我正在尝试使用colander来定义一个可以接受任何类型的SchemaNode。我希望它能够直接接收从JSON反序列化得到的数据,然后把这些数据传递下去。这样做可以吗?

class Foo(colander.MappingSchema):
    name = colander.SchemaNode(colander.String(), validator=colander.Length(max=80))
    value = colander.SchemaNode(??) # should accept int, float, string...

2 个回答

1

我只需要把数据从一种格式转换成另一种格式,所以我用了SpiritMachine的答案的简化版:

class AnyType(colander.SchemaType):
    def deserialize(self, node, cstruct):
        return cstruct

我可能会稍后添加一些功能,用来检测日期和时间。

3

这些Colander类型是从SchemaType派生出来的,并且实现了实际进行序列化和反序列化的方法。

我能想到的唯一方法就是自己写一个SchemaType的实现,这个实现基本上是一个包装器,用来测试值并应用Colander中定义的某种类型。

我觉得这并不会太难,只是看起来不太美观。

编辑:这里有一个简单的例子。我还没有测试过,但它传达了这个想法。

class AnyType(SchemaType):

    def serialize(self, node, appstruct):
        if appstruct is null:
            return null

        impl = colander.Mapping()  # Or whatever default.
        t = type(appstruct)

        if t == str:
            impl = colander.String()
        elif t == int:
            impl = colander.Int()
        # Test the others, throw if indeterminate etc.

        return impl.serialize(node, appstruct)

    def deserialize(self, node, cstruct):
        if cstruct is null:
            return null

        # Test and return again.

撰写回答