在Python中结合棉花糖模式定义和OO的最佳实践是什么?

时间:2017-08-21 21:27:10

标签: python oop marshmallow

假设在marshmallow中定义了一个简单的模式

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可供参考以确定要使用的字段,我可以引用marshmallow模式,但这感觉非常间接。

代码生成

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

对于代码的用户,他们不需要知道使用了codegen方法 - 所有内容都使用显式API,文档可以与readthedocs中的其余代码一起显示等。

动态类

另一种方法是从棉花糖定义派生的动态类。同样,据我所知,没有这样的库(虽然python中动态类生成方法的范围令人印象深刻,但我可能已经错过了一些)。可以说这不会对jsobjects方法产生太大的影响,但可能会有一些优点 - 可以将它与一些具有已定义行为的显式代码交织在一起。动态方法的缺点是,在Python世界中,显式优于隐式。

什么是最pythonic?

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

1 个答案:

答案 0 :(得分:0)

您的问题很模糊,我的答案也将如此,主观上我希望可以。我只是花了整整一天时间阅读python中的序列化选项的家伙。

我认为棉花糖从根本上讲不是Python的,并且没有很好的使用方式,我不打算使用它。我给我举两个确定的例子。

  1. 您有一个类,其中包含其他对象的混合类型列表作为字段。这是python,因此您可以这样做。在棉花糖中,您不能原生或整洁地处理它。有一个非常自然的解决方案,那就是使用已注册的序列化程序放下/列出类。但是在棉花糖中,您必须编写自己的代码并更改每个可能的类的序列化程序,以确保将其注册到传递给嵌套函数的内容中。它没有为类注册序列化程序,您必须添加它。 Issue describing.
  2. 您想将字符串的混合(文字)字典序列化为未知类。这和上面的差不多,您必须自己实现。另外,您必须为每个要执行此操作的原语自己编写一个序列化器/ de。他们为基元编写的代码作为字段而非模式编写,对我而言,这不是包含电池或一种显而易见的方式。

常规序列化库有点像个深坑,因为您真正要谈论的是一口气就需要类型系统,解析器和图遍历算法的元素。棉花糖默认情况下不进行递归解析,因此它失败了第(2)点。在第(1)点,(由于2的原因),它要么需要大量的黑客攻击,要么需要您接受类似Java的类型系统(所有都是已知的枚举类型)。

您询问了有关常规序列化库的信息,我发现库骆驼很有趣,并且围绕它发布了博客文章。对于pickle,有一个功能强大的扩展名为dill,还有一个处理versioning的mixin