Custom Dictionary Representation of Python Dataclass
I've really enjoyed the shortcuts provided by Python's dataclasses.
Recently, I found myself working with an API that required camelCase keys, but I wanted to keep my Python keys in snake_case as I find it comforting.
Creating a dataclass
I created the following dataclass for working with cell locations in Google Sheets:
from dataclasses import dataclasses
@dataclass
class Coordinate:
sheet_id: int
row_index: int
column_index: int
To instantiate an object:
coord = Coordinate(0, 1, 3) # cell D2
Turning the object into a dictionary
The dataclasses.asdict() function transforms your dataclass object. It reuses your declared key names. For example:
from dataclasses import asdict
expected = {
"sheet_id": 0,
"row_index": 1,
"column_index": 3
}
actual = asdict(coord)
assert(expected == actual) # True
Making a custom dict factory
asdict() accepts an optional parameter dict_factory which is a function that tells asdict how to parse the dataclass object.
# help us transform the keys strings
def snake_case_to_camel_case(value: str) -> str:
# split character and remove underscores
data_list: list[str] = data.split("_")
# capitalize the first letter of all words except the first
for i in range(1, len(data_list)):
data_list[i] = data_list[i][0].upper() + data_list[i][1:]
return "".join(data_list)
# our method to plug into `asdict()`
def camel_case_dict_factory(data):
return {snake_case_to_camel_case(field[0]): field[1] for field in data}
To use this new factory:
expected = {
"sheetId": 0,
"rowIndex": 1,
"columnIndex": 3
}
actual = asdict(
coord, dict_factory=camel_case_dict_factory
)
assert(expected == actual) # True
For reference, here's the standard implementation of asdict().