Advanced Python Dataclasses
Also Known As
dataclass
frozen dataclass
slots dataclass
field()
TL;DR
Dataclasses auto-generate __init__, __repr__, __eq__ from field declarations — advanced features include frozen (immutable), slots (memory-efficient), and field metadata.
Explanation
Basic dataclasses auto-generate boilerplate. Advanced: frozen=True makes instances immutable (like PHP readonly), slots=True uses __slots__ for memory efficiency (Python 3.10+), field(default_factory=list) for mutable defaults, post_init for validation, KW_ONLY for keyword-only fields. @dataclass(order=True) generates comparison methods. Combine with __post_init__ for validation logic. For data validation with coercion, use Pydantic; for pure data containers, dataclasses are simpler.
Common Misconception
✗ Dataclasses and Pydantic are interchangeable — dataclasses are lightweight containers with no validation; Pydantic validates and coerces input, making it better for external data.
Why It Matters
Dataclasses eliminate 80% of class boilerplate for data containers — frozen dataclasses provide PHP-like readonly behaviour, slots reduce memory by 40%+ for instances created in large numbers.
Common Mistakes
- Mutable default argument: @dataclass class Foo: items: list = [] — use field(default_factory=list).
- Not using frozen=True for value objects — mutable 'value objects' are not true value objects.
- Comparing dataclasses without order=True — __lt__/__gt__ not generated by default.
- Using dataclasses where Pydantic is needed — dataclasses don't validate or coerce types at runtime.
Code Examples
✗ Vulnerable
# Mutable default — shared across all instances:
@dataclass
class Order:
items: list = [] # BUG: all Order instances share the same list!
o1 = Order(); o2 = Order()
o1.items.append('widget')
print(o2.items) # ['widget'] — shared reference!
✓ Fixed
from dataclasses import dataclass, field
from typing import ClassVar
@dataclass(frozen=True, slots=True) # Immutable + memory-efficient
class Money:
amount: int # Cents
currency: str
CURRENCIES: ClassVar[set] = {'USD', 'EUR', 'GBP'}
def __post_init__(self):
if self.currency not in self.CURRENCIES:
raise ValueError(f'Unknown currency: {self.currency}')
if self.amount < 0:
raise ValueError('Amount cannot be negative')
@dataclass
class Order:
items: list = field(default_factory=list) # Correct mutable default
Tags
🤝 Adopt this term
£79/year · your link shown here
Added
15 Mar 2026
Edited
22 Mar 2026
Views
64
🤖 AI Guestbook educational data only
|
|
Last 30 days
Agents 0
No pings yet today
No pings yesterday
ChatGPT 16
Amazonbot 14
Perplexity 9
Google 7
Unknown AI 4
Ahrefs 2
Meta AI 2
Also referenced
How they use it
crawler 51
crawler_json 1
pre-tracking 2
Related categories
⚡
DEV INTEL
Tools & Severity
🟢 Low
⚙ Fix effort: Medium
⚡ Quick Fix
Use __post_init__ for validation in dataclasses; use field(default_factory=list) not mutable defaults; combine with @dataclass(frozen=True) for immutable value objects
📦 Applies To
python 3.7
web
cli
🔗 Prerequisites
🔍 Detection Hints
@dataclass with mutable default list=[]; no validation in __post_init__; using regular class with manual __init__ when dataclass would simplify
Auto-detectable:
✓ Yes
pylint
ruff
mypy
⚠ Related Problems
🤖 AI Agent
Confidence: Low
False Positives: Medium
✗ Manual fix
Fix: Medium
Context: Class