Unit 3.3 · about 5 h
12 / 324Attribute lookup, object protocols and dataclasses
Config and record objects cross every boundary in later stages. Lookup, equality and default rules decide what breaks silently.
- explain
- implement
You can now
- Trace attribute lookup through data descriptors, the instance dictionary, non-data descriptors and the MRO without running code.
- Implement a class with deliberate dunders and state the equality and hashing consequences.
- Build a validated frozen dataclass with safe defaults, serialization and malformed-input tests.
Covers
- Attribute lookup, class and instance state, and method binding
- Core object protocols and deliberate dunder methods
- Dataclasses, default factories, equality, ordering and frozen state
Study, in this order
7 steps
- Special methodsStas' Python Cookbook - selected path
Classes and Objects: Dunder (special) methods with the
Vectorexample;__repr__for developers and__str__for users - Attribute access and delegationStas' Python Cookbook - selected path
Classes and Objects: Dynamic attributes and delegation;
__getattr__runs only after normal lookup failsDepth · Skip the Null-object/Dummy classes subsection. A catch-all
__getattr__hides typos and works against this unit's explicitness goal. - Special method lookup and attribute accessPython language reference
Section 3.3.13 Special method lookup (implicit calls bypass the instance) and 3.3.2 Customizing attribute access (
__getattribute__versus__getattr__) - The `@dataclass` decorator and fieldsdataclasses - data classes
The
@dataclassparameters (eq,order,frozen,slots),field()withdefault_factory, Frozen instances and Post-init processing - Dataclass helpersdataclasses - data classes
asdict,astupleandreplacefor serialization and copy-with-change - Dunder MethodsAlgoMaster Python - structured revision
The Dunder Methods lesson and its exercise for recall
- Data ClassesAlgoMaster Python - structured revision
The Data Classes lesson and Exercise: Data Classes after the cookbook pass
Focus on
- Lookup order is data descriptors, then the instance dictionary, then non-data descriptors and class attributes. Implicit dunder calls use the type only, so an instance
__len__attribute never changeslen(obj). object.__eq__is identity by default. Defining__eq__without__hash__sets__hash__toNoneand the instances become unhashable.- Dataclass mutable defaults raise
ValueErrorat class creation;field(default_factory=list)gives each instance its own list. - The cookbook writes
Config(frozen=True). That call is wrong and raisesTypeError;frozenbelongs on the decorator as@dataclass(frozen=True).
Reproduce closed-book
__post_init__ checks, an asdict round trip and a replace() change. State why its instances are hashable and which line breaks if frozen is removed.Traps
- Setting an instance
__len__to changelen(). Implicit lookup skips the instance dictionary. - Expecting
<on a default dataclass to work.orderdefaults toFalse, soP(1) < P(2)raisesTypeError. - Sharing state through a plain
listdefault. The decorator rejects it withValueError; read that error as protection.
Practice
AlgoMaster Python: Exercise: Data Classes
Exercises 1 to 5, especially Exercise 2: Compare Products by Field Values and Exercise 4: Give Each Cart Its Own Item List
Use for recall; the frozen dataclass in Reproduce is the implement-depth check.
Self-test
-
A data descriptor, an instance entry and a plain class attribute all define
x. Which doesobj.xreturn?The data descriptor wins. Instance lookup only beats non-data descriptors and plain class attributes. -
A class defines
__eq__but no__hash__. What doeshash(instance)do?It raisesTypeError. Defining__eq__sets__hash__toNoneunless__hash__is also defined. -
What happens at class creation for
tags: list = []inside@dataclass, and what is the fix?ValueError: mutable default is not allowed. Usetags: list = field(default_factory=list). -
Why does removing
frozen=Truefrom a hashed dataclass break set membership?Instances become unhashable becauseeqwithoutfrozensets__hash__toNone. Mutable hashed instances are worse: edits strand them in the wrong bucket.
Completion criterion
Stop when
Your frozen dataclass validates, serializes and round-trips, and you can trace a lookup and an equality case without running code.
Mark passed, then open 3.4 Only mark this when you can do it without notes.Leads to
- 3.7 Type hints, generics, protocols and narrowing Add static types and Protocols to these records.
- 3.4 Iterators, generators and lazy pipelines The iteration protocol in depth:
__iter__,__next__and exhaustion.
Comes after
- 3.2 Argument binding, scope and closuresClass blocks scope names differently from function blocks.
- 3.5 Decorators, wrappers and parameterized decorators
@propertyand@classmethoduse decorator syntax over the descriptor protocol. - 3.7 Type hints, generics, protocols and narrowingCombine dataclasses with Protocols and precise field types.
Resources for this unit
- Stas' Python Cookbook - selected path Run Part I on dictionaries, iteration, functions, closures, decorators, classes and context managers; Part II on modules, files, paths, environment and arguments; and Part IV on versions, dependencies, packaging and code quality. Finish by building one src-layout package from a blank directory.
- Python language reference Check Data model, Execution model, Import system and Exceptions whenever a claim depends on Python semantics. These pages are the authority when the course and a runtime observation disagree.
- AlgoMaster Python - structured revision Use Functions, Modules and Packages, OOP, Advanced OOP, Exception Handling, Iterators and Generators, Type Hints and Annotations only after the cookbook pass. Open it for recall practice or a diagnosed weak mechanism, not as a second complete course.
- dataclasses - data classes Read the
@dataclassparameters (eq,order,frozen,slots),field()withdefault_factory, frozen instances, post-init processing,replace,asdictandastuple. Use for the validated frozen dataclass in attributes-protocols-dataclasses.
Also in this section
- Packaging Python Projects Follow the packaging tutorial once from a blank directory, using a src layout, pyproject.toml, an isolated build and a clean-environment installation test.
- typing - type hints and protocols Read Protocols for structural typing and
runtime_checkablelimits, Generics forTypeVargenerics, andassert_typefor narrowing checks. Use for theProtocoland narrowing parts of type-hints-protocols; PEP 695 syntax itself is in the language reference. - gc - cycle garbage collector Read the cycle collector interface:
collect,get_count,garbageanddisable/enable. Use for the cycle-collection and measurement parts of refcounting-gc-weakrefs. - weakref - weak references Read weak-reference objects (
refcallbacks,proxyobjects) and theWeakValueDictionaryexample. Use for the weak-reference part of refcounting-gc-weakrefs.