Frozen and Comparison Options
Make immutable, ordered dataclasses.
Frozen and Comparison Options is a free Python Academy lesson on CoddyKit — lesson 3 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Python Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Decorator Options
The @dataclass decorator accepts keyword arguments that control which methods it generates. The most useful are frozen and order.
frozen=Truemakes instances immutable.order=Trueadds comparison operators.
Frozen Dataclasses
With frozen=True the generated class blocks attribute assignment after construction. Any attempt raises FrozenInstanceError.
from dataclasses import dataclass, FrozenInstanceError
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
try:
p.x = 99
except FrozenInstanceError as e:
print('Cannot modify:', e)Why Immutability Helps
Immutable objects are easier to reason about: their value never changes after creation, so they are safe to share across functions and threads. They are also safe as dictionary keys and set members.
Frozen Means Hashable
A frozen dataclass is hashable by default, so you can use instances in sets or as dict keys. Mutable dataclasses are not hashable unless you opt in.
from dataclasses import dataclass
@dataclass(frozen=True)
class Point:
x: int
y: int
seen = {Point(0, 0), Point(1, 1), Point(0, 0)}
print(len(seen))Replacing Frozen Values
Since you cannot mutate a frozen instance, use dataclasses.replace() to make a modified copy. The original stays untouched.
from dataclasses import dataclass, replace
@dataclass(frozen=True)
class Point:
x: int
y: int
p = Point(1, 2)
q = replace(p, y=99)
print(p)
print(q)Ordered Dataclasses
By default a dataclass only supports ==. Add order=True to also generate <, <=, >, and >=.
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
print(Version(1, 2) < Version(1, 5))
print(Version(2, 0) > Version(1, 9))How Ordering Compares
Ordering compares fields as a tuple, left to right, in the order they were declared. The first field is the most significant.
from dataclasses import dataclass
@dataclass(order=True)
class Version:
major: int
minor: int
# major compared first, then minor
print(Version(1, 9) < Version(2, 0))Sorting Dataclass Instances
Because ordered dataclasses define the comparison operators, you can sort a list of them directly with sorted().
from dataclasses import dataclass
@dataclass(order=True)
class Score:
points: int
name: str
data = [Score(50, 'B'), Score(90, 'A'), Score(70, 'C')]
for s in sorted(data):
print(s)Controlling the Sort Key
To sort by something other than the natural field order, put a hidden sort field first with field(init=False) and set it in __post_init__. The other fields can be excluded from comparison with compare=False.
from dataclasses import dataclass, field
@dataclass(order=True)
class Item:
sort_index: int = field(init=False, repr=False)
name: str = field(compare=False, default='')
priority: int = 0
def __post_init__(self):
self.sort_index = self.priority
print(Item(name='b', priority=2) > Item(name='a', priority=1))Combining frozen and order
You can combine options. A frozen, ordered dataclass makes a perfect immutable, comparable value type, ideal for keys, version numbers, or coordinates.
from dataclasses import dataclass
@dataclass(frozen=True, order=True)
class SemVer:
major: int
minor: int
patch: int
versions = {SemVer(1, 0, 0): 'stable'}
print(SemVer(1, 0, 0) < SemVer(1, 1, 0))
print(versions[SemVer(1, 0, 0)])eq and the Default
The eq option controls whether __eq__ is generated. It is True by default. Note that order=True requires eq=True, since ordering builds on equality.
from dataclasses import dataclass
@dataclass(eq=True)
class Tag:
name: str
print(Tag('x') == Tag('x'))
print(Tag('x') == Tag('y'))Quick Check
What happens if you assign to a field on a frozen dataclass instance?
Recap
You learned to make immutable, ordered dataclasses.
frozen=Trueblocks mutation and makes instances hashable.- Use
replace()for modified copies. order=Truegenerates comparison operators that compare fields as a tuple.- Combine both for solid value types.
Frequently asked questions
Is the “Frozen and Comparison Options” lesson free?
Yes — the full text of “Frozen and Comparison Options” is free to read here on the web, and the Python Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Python Academy course, upgrade to CoddyKit PRO.
What will I learn in “Frozen and Comparison Options”?
Make immutable, ordered dataclasses. You practise Python Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Python Academy?
No prior experience is required. Python Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 3 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Frozen and Comparison Options” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Python Academy lesson?
Yes. Every Python Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Defining a Dataclass
- Default Values and field()
- Frozen and Comparison Options
- The attrs Library