Skip to main content

定义可序列化类的库。

项目描述

SerialObject 是一个支持从/到类似 json 的对象(字典和内置类型列表)的序列化的对象。

序列化规范取自__fields__类属性,其形式为:

__fields__: {
    FIELD_NAME: FIELD_SPEC
}

FIELD_NAME 是一个字符串,它唯一的约束是它应该是一个有效的对象属性名称。

FIELD_SPEC 可以是:

  • 来自以下的任何本机类型:

    • 字符串

    • 统一码(Python2)

    • 整数

    • 漂浮

    • 布尔

    • 听写

  • SerialObject

  • Choice(val1, val2, ...)形成枚举,值应该是

    本机类型(见上文)。

  • [FIELD_SPEC]:上述规范描述的对象列表。

此外,SerialObjects 支持__strict__布尔类属性(默认为 False)。当__strict__ == True 时,在(反)序列化期间执行穷举检查,并且缺少或未知的键会产生错误。

在 Python2 上,str实例被自动强制转换为 unicode 字符串。

安装

serialobj在 PyPi 上注册。只需键入以下命令。

pip install serialobj

或者,您可以在克隆源存储库后运行以下命令:

python setup.py install

快速教程

简单类型和继承

让我们定义一个非常基本的 Person 类型,它定义了两个字符串字段:

class Person(SerialObject):
    __fields__ = {
        'name': str,
        'job': str
    }

现在我们可以简单地将与 json 兼容的数据反序列化为它,和/或将其实例序列化为类似 json 的结构:

>>> person_data = {
...     'name': 'Bob',
...     'job': 'lumberjack'
... }
>>> bob = Person.deserialize(person_data)
>>> bob.name
'Bob'
>>> bob.job
'lumberjack'
>>> bob.serialize()
{'job': 'lumberjack', 'name': 'Bob'}

当然,还有更多。让我们将Person子类化,例如定义一个TeamMate,它会覆盖job字段以使其成为dict并添加一个新的str字段:role

class TeamMate(Person):
    __fields__ = {
        'role': str,
        'job': dict
    }

当然这是一个愚蠢的例子,但这让我们可以证明继承SerialObject类允许继承、覆盖和专门化结构定义:

>>> bob2 = TeamMate.deserialize(teammate_data)
>>> bob2.name
'Bob'
>>> bob2.job
{'all night': 'sleep', 'all day': 'work'}
>>> bob2.serialize()
{'role': 'lumberjack', 'name': 'Bob', 'job': {'all night': 'sleep', 'all day': 'work'}}

它还允许我们证明结构实际上是根据模型检查 的:让我们尝试使用不兼容的Person模型反序列化我们的teammate_data

>>> Person.deserialize(teammate_data)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
    Person.deserialize(teammate_data)
  File "/home/arnaud/work/serialobj/serialobj.py", line 242, in deserialize
    for key, val in data.items() if key in cls.__fields__
  File "/home/arnaud/work/serialobj/serialobj.py", line 242, in <dictcomp>
    for key, val in data.items() if key in cls.__fields__
  File "/home/arnaud/work/serialobj/serialobj.py", line 86, in deserialize
    .format(self.cls_.__name__, data))
serialobj.InvalidTypeError: Expected str, got {'all night': 'sleep', 'all day': 'work'}

是不是开始变得有趣了?

对象列表

让我们稍微调味。如果我想将字段定义为字符串列表怎么办?

好吧,这有一些糖:

class Task(SerialObject):
    __fields__ = {
        'title': str,
        'description': str,
        'checklist': [str]
    }

你自己看:

>>> data = {
...     'title': 'timber some wood',
...     'description': '',
...     'checklist': [
...         'some wood is timbered',
...         'the lumberjack is okay',
...         'he sleeps all night and works all day'
...     ]
... }
>>> tsk = Task.deserialize(data)
>>> tsk.checklist
['some wood is timbered', 'the lumberjack is okay', 'he sleeps all night and works all day']
>>> tsk.checklist.append("... and that's it")
>>> pprint(tsk.serialize())
{'checklist': ['some wood is timbered',
               'the lumberjack is okay',
               'he sleeps all night and works all day',
               "... and that's it"],
 'description': '',
 'title': 'timber some wood'}

变得花哨

当然,所有这些都是定义任意复杂 JSON-API 结构的基础构建块:

class Team(SerialObject):
    __fields__ = {
        'name': str,
        'manager': TeamMate,
        'members': [TeamMate],
        'backlog': [Task]
    }


COMPLEX_DATA = {
    'name': "The good ol' lumberjacks",
    'manager': {
        'name': 'Bob',
        'role': 'Be okay'
    },
    'members': [
        {
            'name': 'Jack',
            'role': 'sleep all night'
        },
        {
            'name': 'Barry',
            'role': 'work all day',
        }],
    'backlog': [
        {
            'title': 'timber some wood',
            'description': '',
            'checklist': [
                'some wood is timbered',
                'the lumberjack is okay',
                'he sleeps all night and works all day'
            ]
        }]
    }

开始了:

>>> team = Team.deserialize(COMPLEX_DATA)
>>> team.manager.name
'Bob'
>>> team.manager
<__console__.TeamMate object at 0x7f34edd2c9a8>
>>> team.backlog[0]
<__console__.Task object at 0x7f34edd9b7c8>
>>> team.backlog[0].title
'timber some wood'
>>> pprint(team.serialize())
{'backlog': [{'checklist': ['some wood is timbered',
                            'the lumberjack is okay',
                            'he sleeps all night and works all day'],
              'description': '',
              'title': 'timber some wood'}],
 'manager': {'name': 'Bob', 'role': 'Be okay'},
 'members': [{'name': 'Jack', 'role': 'sleep all night'},
             {'name': 'Barry', 'role': 'work all day'}],
 'name': "The good ol' lumberjacks"}

测试

您可以使用tox触发所有测试。目前正在为 python 2.7 和 3.5 运行测试。

下载文件

下载适用于您平台的文件。如果您不确定要选择哪个,请了解有关安装包的更多信息。

源分布

serialobj-0.8.1.tar.gz (6.7 kB 查看哈希

已上传 source

内置分布

serialobj-0.8.1-py2.py3-none-any.whl (9.6 kB 查看哈希

已上传 py2 py3