TL;DR
If you’re using Python 3.7+, dataclasses will save you a bunch of time, make your code cleaner, and maybe even make your code more correct.
Why you should not use a dataclass
- 🕸 You’re stuck on a Python version < 3.7. I’m sorry for you, 3.7 adds several really great features, so upgrade whenever you can.
- 🚫 There is no 2. If you’re using Python 3.7+ dataclasses will almost certainly help you at some point.
What’s a dataclass?
I’m glad you asked 🤓! Python 3.7 added a neat little decorator called @dataclass
. Rather than try to explain in English why it’s awesome, I’ll just show you.
What you write
from dataclasses import dataclass, field
from typing import List
@dataclass
class Pizza:
# Each of these is called a field
crust: str
has_cheese: bool = True
toppings: List[str] = field(default_factory=list)
What you can now do
from dataclasses import asdict, astuple, replace
# An __init__ is created which takes all fields as args or kwargs!
thick_cheesy = Pizza(crust='thick')
# __repr__ is generated, exclude any fields you don’t want
print(thick_cheesy)
# Prints "Pizza(crust='thick', has_cheese=True, toppings=[])"
# Handy method to create a dict, only includes fields
d = asdict(thick_cheesy)
assert d == {
'crust': 'thick',
'has_cheese': True,
'toppings': [],
}
# Create a new object based on another object
with_olives = replace(thick_cheesy, toppings=['olives'])
# Make a tuple from the fields
t = astuple(with_olives)
assert t == ('thick', True, ['olives'])
# __eq__ is generated
assert with_olives != thick_cheesy # Effectively compares as tuples
But wait, there’s more! 💸
With a few options passed to the @dataclass
decorator, you can also:
- Make your newly formed objects immutable (AKA frozen 🥶)
- Load additional attributes that don’t show up as fields (aren’t in asdict either!)
- Quickly add comparators (<, >, etc.)
Not Sold?
If dataclasses don’t immediately make you excited, why not? I’d love to read your comment.