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().

Get Notified of New Posts

Sign up for the newsletter and I'll send you an email when there's a new post.