What You'll Master Here
A decorator returns a replacement function. A context manager guarantees the exit. A dataclass writes the boilerplate a record contract implies.
This is the chapter behind "do you actually know Python, or do you know pandas". Decorators, context managers and dataclasses are the three constructs that separate somebody who writes scripts from somebody who writes code other people maintain — and all three are asked about directly in almost every Python screen.
They are also the three that people use daily without being able to explain. `@retry` is copied from a colleague, `with open(...)` is muscle memory, `@dataclass` is "the thing that saves typing `__init__`". Each of those is true and none of them is the answer an interviewer is listening for.
The through-line is contracts. A decorator wraps a contract without changing it. A context manager guarantees a contract at the exit, however the block ends. A dataclass makes a record's contract explicit enough that equality, hashing and serialisation come for free.
A decorator returns a replacement function. A context manager guarantees the exit. A dataclass writes the boilerplate a record contract implies.
Retry wrappers, timing wrappers, batch scopes, transaction scopes and typed records are the standard furniture of production pipeline code. Reading it, reviewing it and writing it all start here.
- first-class function
- A function you can pass, store and return like any other object.
- decorator
- A callable that takes a function and returns a replacement for it.
- context manager
- An object with `__enter__` and `__exit__`, used by `with` to guarantee cleanup.
- dataclass
- A class decorator that generates `__init__`, `__repr__` and `__eq__` from annotated fields.
- Protocol
- A structural type: anything with the right methods satisfies it, with no inheritance.
Using all three by copy-paste, and being unable to say what any of them returns. Every follow-up question in an interview goes unanswered, and in review you cannot tell a decorator that preserves behaviour from one that quietly swallows an exception.
Read `@thing` as "rebind this name to `thing(this_function)`", every time.
Ask of any `with` block: what is guaranteed when this exits, including by exception?
Reach for a dataclass the moment a dict's keys have become a contract other code relies on.
Every construct here is introduced by writing it out longhand first, then by the syntax sugar. The sugar is easy; knowing what it expands to is the part being tested.
These three come up as definitions ("what is a decorator?"), as output prediction ("what does this print?") and as code review ("what would you change?"). The same understanding answers all three; the surface differs.
Decorators, context managers and dataclasses are three ways of making a contract explicit — around a call, around a block, and around a record.
