January 30, 2025

About

How can we efficiently assign values to member variables? Using __annotations__ is one approach, but dataclasses or Pydantic’s BaseModel might offer better solutions.

class Example:
    a: int
    b: str = "default"
    c: float

    def __init__(self, c: float):
        self.c = c

# check __annotations__ of a class
print("Class __annotations__:", Example.__annotations__)
# {'a': <class 'int'>, 'b': <class 'str'>, 'c': <class 'float'>}


def add_numbers(x: int, y: int) -> int:
    return x + y

# check __annotations__ of a function
print("Function __annotations__:", add_numbers.__annotations__)
# {'x': <class 'int'>, 'y': <class 'int'>, 'return': <class 'int'>}

dataclass

from dataclasses import dataclass, fields, Field

@dataclass
class MyDataClass:
    a: int = 10
    b: str = "default"
    c: float = 3.14

    @classmethod
    def from_defaults(cls, **kwargs):
        defaults = {f.name: f.default for f in fields(cls) if f.default is not Field.default}
        # overwrite defaults by `kwargs`
        combined = {**defaults, **kwargs}
        return cls(**combined)

obj1 = MyDataClass.from_defaults()
print(obj1)  # MyDataClass(a=10, b='default', c=3.14)

obj2 = MyDataClass.from_defaults(a=20, c=1.23)
print(obj2)  # MyDataClass(a=20, b='default', c=1.23)