0Pricing
Python Academy · Lesson

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=True makes instances immutable.
  • order=True adds 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=True blocks mutation and makes instances hashable.
  • Use replace() for modified copies.
  • order=True generates 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

  1. Defining a Dataclass
  2. Default Values and field()
  3. Frozen and Comparison Options
  4. The attrs Library
← Back to Python Academy