Уже больше года мы на своем проекте используем отличный инструмент cattrs. Он показался мне на столько классным, что я даже написал еще один инструмент на его основе — apitist (о нем я расскажу как-нибудь позже). Инструмент позволяет с легкостью работать с моделями данных — дает возможность преобразовывать из словарей и списков данные в объекты моделей и обратно.
Под капотом cattrs использует библиотеку attrs. Она в свою очередь позволяет быстро делать классы:
>>> @attr.s
... class Coordinates(object):
... x = attr.ib()
... y = attr.ib()
>>> c1 = Coordinates(1, 2)
>>> c1
Coordinates(x=1, y=2)
>>> c2 = Coordinates(x=2, y=1)
>>> c2
Coordinates(x=2, y=1)
>>> c1 == c2
False
Ну, не то чтобы прямо под капотом, скорее cattrs умеет структурировать и деструктурировать данные из attrs классов. Благодаря этому cattrs позволяет работать на Python версии 2.7 и >3.5.
В Python 3.7 появился похожий функционал в стандартной библиотеке — dataclasses. А благодаря ericvsmith этот функционал был перенесен на Python 3.6.
Мне было интересно и я решил перенести функционал cattrs на dataclasses. Результатом стала библиотека convclasses, которая позволяет делать так:
from enum import unique, Enum
from typing import Any, List, Optional, Sequence, Union
from convclasses import structure, unstructure
from dataclasses import dataclass
@unique
class CatBreed(Enum):
SIAMESE = "siamese"
MAINE_COON = "maine_coon"
SACRED_BIRMAN = "birman"
@dataclass
class Cat:
breed: CatBreed
names: Sequence[str]
@dataclass
class DogMicrochip:
chip_id: Any
time_chipped: float
@dataclass
class Dog:
cuteness: int
chip: Optional[DogMicrochip]
p = unstructure([
Dog(cuteness=1, chip=DogMicrochip(chip_id=1, time_chipped=10.0)),
Cat(breed=CatBreed.MAINE_COON, names=('Fluffly', 'Fluffer'))
])
print(p)
# [{'cuteness': 1, 'chip': {'chip_id': 1, 'time_chipped': 10.0}}, {'breed': 'maine_coon', 'names': ('Fluffly', 'Fluffer')}]
print(structure(p, List[Union[Dog, Cat]]))
# [Dog(cuteness=1, chip=DogMicrochip(chip_id=1, time_chipped=10.0)), Cat(breed=<CatBreed.MAINE_COON: 'maine_coon'>, names=['Fluffly', 'Fluffer'])]
Благодаря этим библиотекам можно быстро и просто производить тестирование REST API использующее JSON.
Более подробно расскажу как-нибудь потом, а на этом анонс alles.