19

假设在棉花糖中定义了一个简单的模式

class AddressSchema(Schema):
    street=fields.String(required=True)
    city=fields.String(required=True)
    country=fields.String(default='USA')

class PersonSchema(Schema):
    name=fields.String(required=True)
    address=fields.Nested(AddressSchema())

这里的用例是使用内存对象的应用程序,以及对 JSON 的序列化/反序列化,即没有 SQL 数据库。

使用标准json库,我可以解析符合此模式的 JSON 对象,并以person1['address']['city'].

手工制作的OO模型

我可以定义一个并行的 OO 模型,并用@post_load装饰器注释我的模式,例如:

class Address(object):
    def __init__(self, street, city, country='USA'):
        self.street=street
        self.city=city
        self.country=country

class Person(object):
    def __init__(self, street, city=None):
        self.street=street
        self.city=city

但是重复不是很好(我什至没有在模式中包含描述)。

无 OO 模型

可以说,显式 OO 模型并不买太多——它是基本的数据访问器,没有行为。我可以使用jsobject获得一些语法糖,以便我可以编写示例person1.address.city。但这似乎也不完全正确。作为一名开发人员,我没有明确的 python 类 API 可以参考以确定要使用的字段,我可以引用棉花糖模式,但这感觉非常间接。

代码生成

从棉花糖模式定义中生成上面的 OO 代码相当容易。我很惊讶似乎没有这样的图书馆。也许代码生成被认为是非常不合时宜的?它当然只适用于数据访问风格的类定义;添加非通用行为将严格禁止。

对于代码的用户,他们不需要知道使用了 codegen 方法 - 一切都将有一个明确的 API,文档与 readthedocs 中的其余代码一起可见。

动态类

另一种方法是从棉花糖定义派生的动态类。同样,据我所知,没有这样的库(尽管 python 中动态类生成方法的范围令人印象深刻,但我可能错过了一些)。可以说,与 jsobjects 方法相比,这不会给你带来太多好处,但可能会有一些优势 - 可以将它与一些具有定义行为的显式代码交织在一起。动态方法的缺点是在 Python 世界中显式优于隐式。

什么是最蟒蛇?

这里缺少库意味着我要么找不到东西,要么没有以适当的 Python 方式看待这个。我很高兴为 pypi 贡献一些东西,但在添加另一个元 OO 库之前,我想确定我已经在这里做了尽职调查。

4

1 回答 1

1

你的问题很模糊,我的回答也是如此,而且很主观,我希望没关系。我只是一个花一天时间在 python 中阅读序列化选项的家伙。

我认为 Marshmallow 从根本上讲是 unpythonic,并且没有很好的使用方法,我不打算使用它。我将给出两个明确的例子。

  1. 您有一个类,该类具有其他对象的混合类型列表作为字段。这是python,所以你可以这样做。在 Marshmallow 中,你不能原生或巧妙地处理这个问题。有一个非常自然的解决方案,即通过使用它们注册的序列化器来放下/列出类的列表。但是在 Marshmallow 中,您必须编写自己的代码并更改每个可能的类的序列化程序,以确保它已注册到您传递给嵌套函数的内容中。它没有为类注册序列化程序,您必须添加它。问题描述。
  2. 您想将字符串的混合(文字)字典序列化为未知类。这与上面几乎相同,您必须自己实现它。另外,您必须自己为要执行此操作的每个原语编写一个序列化程序/de。他们将原语的代码编写为字段而不是模式,对我来说,这不是电池或一种明显的方式。

通用序列化库有点像兔子洞,因为你真正谈论的内容需要类型系统、解析器和图遍历算法的元素一次完成。Marshmallow 默认情况下不进行递归解析,因此它失败了第 (2) 点。在第 (1) 点上,(有点因为第 2 点),它要么需要大量的黑客攻击,要么需要您接受类似 java 的类型系统(一切都是已知的枚举类型)。

您询问了通用序列化库,我发现库骆驼很有趣,并且围绕它的博客文章。对于 pickle,有一个名为dill的强大扩展和一个处理版本控制的 mixin

于 2018-11-15T21:21:41.143 回答