AtomLearnAtomLearn
DashboardGoalsPathAchievementsReviewSign In
Python CoreNot Started

OOP Advanced

Dunders, classmethods, staticmethods, dataclasses, and MRO

0%
Knowledge0%
Learn & Drill
Fluency0%
Drill & Speed
Retention0%
Mastery & Review
Confidence0%
All modes
Practice

Free tier: read the explanation here. Upgrade to Pro for Drills, Speed challenges & Mastery badges.

Upgrade
Knowledge
Fluency
Retention

Knowledge Debt detected

You can study this freely — but your score may plateau if these foundations have gaps. The Mastery badge requires them to be solid.

Explanation

Python's OOP goes well beyond basic classes. Here are the patterns you'll see in production code.

:dunder-method[A special method with double underscores that customizes how objects behave with operators and built-in functions, e.g. __init__ or __add__]s — customize how objects behave with operators and built-ins: ``python class Vector: def __init__(self, x, y): self.x, self.y = x, y def __repr__(self): return f"Vector({self.x}, {self.y})" def __add__(self, other): return Vector(self.x + other.x, self.y + other.y) def __len__(self): return 2 v = Vector(1, 2) + Vector(3, 4) # Vector(4, 6)

classmethod vs staticmethod:

python class Temperature: def __init__(self, celsius): self.celsius = celsius @classmethod def from_fahrenheit(cls, f): # cls = the class itself return cls((f - 32) * 5/9) @staticmethod def is_freezing(celsius): # no cls or self — pure utility return celsius <= 0

:dataclass[A decorator that auto-generates __init__, __repr__, and __eq__ from class attributes with type annotations]es — auto-generate __init__, __repr__, __eq__: ``python from dataclasses import dataclass, field @dataclass class Point: x: float y: float label: str = "origin" tags: list = field(default_factory=list) p = Point(1.0, 2.0) # __init__, __repr__, __eq__ all generated automatically

:MRO[Method Resolution Order — the order Python searches for methods in multiple inheritance] (Method Resolution Order) — how Python resolves method calls in multiple inheritance: ``python class A: def greet(self): return "A" class B(A): def greet(self): return "B" class C(A): def greet(self): return "C" class D(B, C): pass # MRO: D → B → C → A D().greet() # "B" — follows MRO left to right print(D.__mro__) # (<class D>, <class B>, <class C>, <class A>, <class object>)

Examples

dataclass with validation

__post_init__ runs after the generated __init__ — great for validation

from dataclasses import dataclass

@dataclass
class User:
    name: str
    age: int
    email: str

    def __post_init__(self):
        if self.age < 0:
            raise ValueError("Age cannot be negative")
        self.email = self.email.lower()

u = User("Alice", 30, "Alice@Example.COM")
print(u)  # User(name='Alice', age=30, email='alice@example.com')

classmethod as alternative constructor

classmethods let you define multiple ways to construct an object

from dataclasses import dataclass
from datetime import date

@dataclass
class Event:
    name: str
    date: date

    @classmethod
    def today(cls, name: str) -> "Event":
        return cls(name, date.today())

    @classmethod
    def from_iso(cls, name: str, iso: str) -> "Event":
        return cls(name, date.fromisoformat(iso))

e = Event.from_iso("Launch", "2026-07-01")

How well did you understand this?

Next in Python Core

Context Managers

Continue