Topic 21 of 64
Dataclasses
Overview
Python's dataclasses (3.7+) automatically generate __init__, __repr__, __eq__, and other methods from class annotations. They're the modern Pythonic way to define data containers without boilerplate.
Syntax
python
from dataclasses import dataclass, field
from typing import Optional
from datetime import datetime
@dataclass
class User:
id: int
name: str
email: str
role: str = "viewer" # default value
tags: list = field(default_factory=list) # mutable default
created_at: datetime = field(default_factory=datetime.now)
_password: str = field(default="", repr=False) # excluded from repr
# Frozen (immutable) dataclass
@dataclass(frozen=True)
class Point:
x: float
y: float
# Order comparison
@dataclass(order=True)
class Product:
sort_index: float = field(init=False, repr=False)
name: str
price: float
def __post_init__(self):
self.sort_index = self.price # sort by price
# Post-init processing
@dataclass
class Circle:
radius: float
area: float = field(init=False)
def __post_init__(self):
self.area = 3.14159 * self.radius ** 2Common Pitfalls
- Never use mutable defaults directly: tags: list = [] — use field(default_factory=list) instead.
- @dataclass(frozen=True) makes instances hashable (usable as dict keys) but immutable.
- Interview tip: dataclasses.asdict() converts a dataclass to a dict recursively — perfect for JSON serialization.
Real-World Example
A type-safe data pipeline using dataclasses:
example
python
from dataclasses import dataclass, field, asdict
from typing import Optional
from datetime import datetime
@dataclass
class Address:
street: str
city: str
pincode: str
state: str = "Maharashtra"
@dataclass
class Customer:
id: int
name: str
email: str
phone: str
address: Address
loyalty_points: int = 0
created_at: datetime = field(default_factory=datetime.now)
def to_dict(self) -> dict:
return asdict(self) # built-in converter!
def add_points(self, amount: int, rate: float = 0.01) -> None:
self.loyalty_points += int(amount * rate)
# Usage
addr = Address(street="123 MG Road", city="Pune", pincode="411001")
customer = Customer(
id=42, name="Priya Sharma",
email="priya@example.com", phone="+91 98765 43210",
address=addr
)
customer.add_points(10000) # ₹10k purchase
print(customer.loyalty_points) # 100 points
# Serialize to JSON
import json
json.dumps(customer.to_dict(), default=str)