PYTHON
Simplify Data Models with Python's `dataclasses` Module
Streamline the creation of data-holding classes using Python's `dataclasses`, automatically generating boilerplate methods like `__init__`, `__repr__`, and `__eq__`.
from dataclasses import dataclass, field
# Define a simple data class for a User
@dataclass
class User:
id: int
name: str
email: str = "[email protected]" # Default value
# Define a data class with a mutable default and post-init processing
@dataclass
class BlogPost:
id: int
title: str
author: User
tags: list[str] = field(default_factory=list) # Mutable default handled correctly
created_at: str = field(init=False, repr=False) # Exclude from init and repr
def __post_init__(self):
# Perform any setup or validation after __init__
import datetime
self.created_at = datetime.datetime.now().isoformat()
# Create instances
user1 = User(1, "Alice")
user2 = User(2, "Bob", "[email protected]")
post1 = BlogPost(101, "Intro to Dataclasses", user1, ['python', 'webdev'])
# Dataclasses provide __repr__, __eq__ automatically
print(f"User 1: {user1}")
print(f"User 2: {user2}")
print(f"Post 1: {post1}")
print(f"Are user1 and a new user with same id/name equal? {user1 == User(1, 'Alice')}")
# Access fields
print(f"Post 1 title: {post1.title}, Author email: {post1.author.email}")
print(f"Post 1 created at (not in repr): {post1.created_at}")
# demonstrate mutable default
post2 = BlogPost(102, "Another Post", user2)
post2.tags.append('new tag')
print(f"Post 1 tags: {post1.tags}") # Original list not affected
print(f"Post 2 tags: {post2.tags}") # New list for post2
How it works: The `dataclasses` module provides a decorator (`@dataclass`) to automatically generate boilerplate methods like `__init__`, `__repr__`, `__eq__`, and `__hash__` for classes primarily used to store data. This significantly reduces the amount of code needed for simple data models, making them cleaner and easier to maintain compared to manually writing these methods. It also offers features like default values, immutable fields, and `field()` options for more control, including correctly handling mutable default arguments using `default_factory`. They are excellent for defining API request/response objects, database entities, or configuration settings.