I’m not an expert. I learn to create a REST API wrapper. I use dataclass
for schema and TypedDict
for types.py
to help the wrapper. When i create both dataclass
and TypedDict
i noticed that it looks very similar. I feel it getting WET and error prone. Let me explain similarity and difference between dataclass
and TypedDict
.
Similarity
Created Using class
dataclass
from dataclasses import dataclass
@dataclass
class AuthorData:
name: str
address: str
age: int
@dataclass
class BookData:
title: str
numberOfPage: int
author: AuthorData
TypedDict
from typing import TypedDict
class AuthorDict(TypedDict):
name: str
address: str
age: int
class BookDict(TypedDict):
title: str
numberOfPage: int
author: AuthorDict
Allowing inheritance
dataclass
from dataclasses import dataclass
@dataclass
class AnimalData:
name: str
@dataclass
class CatData(AnimalData):
color: str
TypedDict
from typing import TypedDict
class AnimalDict(TypedDict):
name: str
class CatDict(AnimalDict):
color: str
Difference
Using attribute vs key
dataclass
book_data.author.name
TypedDict
book_dict['author']['name']
Pass with argument vs pass with dict
dataclass
cat = CatData("Whity", "white")
# Cat(name='Whity', color='white')
TypedDict
cat = CatDict({"name":"Whity", "color":"white"})
# {'name': 'Whity', 'color': 'white'}
Even there is asdict
function in dataclasses
to make it a dict
.
from dataclasses import asdict
@dataclass
class ShopData:
cats: list[CatData]
class ShopDict(TypedDict):
cats: list[CatDict]
shop_data = ShopData([CatData("Browny", "brown"), CatData("Whity", "white")])
# Shop(cats=[CatData(name='Browny', color='brown'), CatData(name='Whity', color='white')])
shop_dict = asdict(shop_data)
# {'cats': [{'name': 'Browny', 'color': 'brown'}, {'name': 'Whity', 'color': 'white'}]}
Example when using with res.json()
data: ShopDict = res.json()
shop = ShopData(**data)
I think the code is more DRY if somehow we have a way to make TypedDict
from dataclass
and make it easier to map json into class. I’ve read there is new typing Unpack
to unpack TypedDict
that make it possible to static type check dict
. How about dataclass
?
data: Unpack[ShopData] = res.json()
shop = ShopData(**data)
Looks good and straightforward right?
Another example is when using **kwargs
to pass argument. This explained at the top.
so what rule eliminates it from the list of options?
I’m still not sure how to solve this