Skip to main content

适用于一般用途的灵活、可扩展的 Python 数据结构

项目描述

用于一般用途的灵活、可扩展的 Python 数据结构。可靠、快速地输入和输出数据,无需样板文件!

middle站在attrs的肩膀上,旨在尽可能简单地从复杂对象获取数据到 Python 原语,反之亦然,使用验证器、转换器、大量糖和其他实用程序!middle可以与您首选的 Web 框架、后台作业应用程序、配置解析器等一起使用!

抢先看

middle的最简单示例及其一些特性(使用 Python 3.6+ 语法):

>>> import typing
>>> import middle

>>> class Address(middle.Model):
...     street_name: str
...     number: typing.Optional[int]
...     city: str

>>> class Person(middle.Model):
...     name: str
...     age: int
...     address: typing.Dict[str, Address]

>>> data = {
...     "name": "John Doe",
...     "age": 42,
...     "address": {
...         "home": {
...             "street_name": "Foo St",
...             "number": None,
...             "city": "Python Park"
...         },
...         "work": {
...             "street_name": "Bar Blvd",
...             "number": "1337",
...             "city": "Park City"
...         }
...     }
... }

>>> person = Person(data)

>>> person
Person(name='John Doe', age=42, address={'home': Address(street_name='Foo St', number=None, city='Python Park'), 'work': Address(street_name='Bar Blvd', number=1337, city='Park City')})

>>> middle.asdict(person)
{'name': 'John Doe', 'age': 42, 'address': {'home': {'street_name': 'Foo St', 'number': None, 'city': 'Python Park'}, 'work': {'street_name': 'Bar Blvd', 'number': 1337, 'city': 'Park City'}}}

想要一个更复杂的示例,使用 Python 3.5 兼容的语法?当然!

>>> from typing import Dict, List
>>> import middle

>>> class Game(middle.Model):
...     name: str = middle.field()
...     score: float = middle.field(minimum=0, maximum=10)
...     resolution_tested: str = middle.field(pattern="^\d+x\d+$")
...     genre: List[str] = middle.field(unique_items=True)
...     rating: Dict[str, float] = middle.field(max_properties=5)

>>> data = {
...     "name": "Cities: Skylines",
...     "score": 9.0,
...     "resolution_tested": "1920x1200",
...     "genre": ["Simulators", "City Building"],
...     "rating": {
...         "IGN": 8.5,
...         "Gamespot": 8.0,
...         "Steam": 4.5
...     }
... }

>>> game = Game(**data)

>>> game
Game(name='Cities: Skylines', score=9.0, resolution_tested='1920x1200', genre=['Simulators', 'City Building'], rating={'IGN': 8.5, 'Gamespot': 8.0, 'Steam': 4.5})

>>> middle.asdict(game)
{'name': 'Cities: Skylines', 'score': 9.0, 'resolution_tested': '1920x1200', 'genre': ['Simulators', 'City Building'], 'rating': {'IGN': 8.5, 'Gamespot': 8.0, 'Steam': 4.5}}

middle足够灵活,可以理解Enum 、嵌套模型和开箱即用的类型模块上声明的各种类型。此外,您可以将其扩展到您自己的类!

去做

  • 用于填充类的别名选项(键);

  • 只读和只写字段;

  • 更好的错误处理(几乎无处不在);

  • 针对其他解决方案创建基准套件;

  • 格式化程序仍然缺失;

  • 可以将一个实例“转换”到另一个实例,其中原始对象是它的子类;

完毕

  • 如果可能,细化转换器,因此 {} 的str输入值不会以str({})结束;

  • 获取可自定义的日期日期时间转换器,而不是if isinstance语句;

  • 实现更多验证器和可注册的更多元数据选项;

  • 基于更复杂的规则(除了functools.singledispatch提供的type(field.type) )实现更好的“类型调度器”,因为类型模块在 Python 3.6 和 3.7 之间发生了一些变化;

  • 支持更多类型(typing.Tupledecimal.Decimal);

  • 获得 100%(或更接近)的代码覆盖率;

  • 大量文档;

  • Python 3.5 支持(Windows 平台除外,请参阅下面针对 Windows 开发人员的警告);

未来的讨论

  • 在 Python 3.7 中,添加了一个简洁的特性:dataclasses。我知道不依赖 3rd-party 库听起来真的很棒——比如attrs ,但是最新版本提供了很多 Python 3.7数据类(目前)找不到的功能,所以我会保持开放状态进一步讨论。

对 Windows 开发人员的警告

如果您使用的是 Windows 和 Python 3.5,我认为middle不适合您。由于这个问题,AppVeyor 中的 CI 在 Python 3.5 中被禁用。如果 Guido 不在乎,我为什么要(或你)?

文档

https://middle.readthedocs.io/en/latest/

v0.2.2 于 2018-10-28

  • 增加了模型具有方法、功能、属性等的可能性。

v0.2.1 于 2018-07-26

  • 与更改日志和 MANIFEST.in 文件相关的快速修复

v0.2.0 于 2018-07-26

  • 发布(部分)文档

  • 获得 99% 的覆盖率(最终合并)

  • 添加了 Python 3.5 支持

v0.1.1 于 2018-07-02

  • 为 Python 3.6 和 3.7 添加适当的单元测试和支持

  • 使 API 更加灵活

  • 代码格式和检查用黑色完成

v0.1.0 于 2018-06-21

  • PyPI 上的第一个版本。

项目详情


下载文件

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

源分布

middle-0.2.4.tar.gz (61.0 kB 查看哈希

已上传 source

内置分布

middle-0.2.4-py3-none-any.whl (20.0 kB 查看哈希

已上传 py3