Exercise Answers¶
Page Maps¶
graph LR
family["Python Programming"]
program["Python Meta-Programming"]
section["Class Customization Pre Metaclasses"]
page["Exercise Answers"]
capstone["Capstone evidence"]
family --> program --> section --> page
page -.applies in.-> capstone
flowchart LR
orient["Orient on the page map"] --> read["Read the main claim and examples"]
read --> inspect["Inspect the related code, proof, or capstone surface"]
inspect --> verify["Run or review the verification path"]
verify --> apply["Apply the idea back to the module and capstone"]
Use this page after attempting the exercises yourself. The point is not to match every example literally. The point is to compare your reasoning against answers that keep class-level power, attribute boundaries, and escalation limits honest.
Answer 1: Use one class decorator for an opt-in class rule¶
Example answer:
A class decorator that registers decorated classes in a plugin registry is a good fit when:
- registration is opt-in
- the class already exists before registration runs
- the effect can be inspected after decoration
Good conclusion:
This does not need a metaclass because the rule does not depend on controlling namespace preparation or class creation itself. The decorator can apply the behavior after the class object already exists.
Answer 2: Separate dataclass generation from validation¶
Example answer:
Generated behavior:
__init____repr__- equality methods
Missing invariant:
ageis not automatically checked to be non-negative
Good conclusion:
The missing rule should live in an explicit validation boundary such as __post_init__, a
property, or a descriptor, depending on how broad the rule becomes.
Answer 3: Control one attribute boundary with a property¶
Example answer:
class Product:
def __init__(self, price):
self.price = price
@property
def price(self):
return self._price
@price.setter
def price(self, value):
if value < 0:
raise ValueError("price must be non-negative")
self._price = value
Good conclusion:
A property is the clearest owner because the rule applies to one field and stays visible exactly where reads and writes cross the attribute boundary.
Answer 4: Promote one repeated property rule into a descriptor¶
Example answer:
Suppose several classes each need string attributes that must be non-empty.
A descriptor is now a better fit because:
- the same rule repeats across multiple attributes or classes
- one reusable owner is clearer than copied property setters
- the rule still lives at the attribute boundary
Good conclusion:
This is still not metaclass control because the descriptor governs how specific attributes behave on access and assignment, not how the class itself is created.
Answer 5: Place one design on the lower-power ladder¶
Example answer:
Requirement:
- keep one
emailfield normalized to lowercase on assignment
Best placement:
- property
Rejected stronger options:
- a descriptor is unnecessary if only one attribute in one class needs the rule
- a metaclass would be extreme overreach because no class-creation control is required
Good conclusion:
Strong answers do not just pick a tool. They explain why a stronger tool would add power without adding clarity.
Answer 6: Review the limits of a frozen surface¶
Example answer:
A minimal @frozen decorator can honestly control:
- reassignment of instance attributes after initialization
- deletion of instance attributes after initialization
It still allows:
- mutation of nested mutable objects such as lists or dictionaries already stored on the instance
Good conclusion:
That remaining mutability does not make the example dishonest as long as the decorator defines frozen as a surface-level attribute rule rather than as universal deep immutability.
What strong Module 06 answers have in common¶
Across the whole set, strong answers share the same habits:
- they separate generated convenience from real invariants
- they keep rules at the smallest honest boundary
- they treat descriptors as reusable attribute owners, not as a shortcut to extra prestige
- they reject metaclass escalation unless class-creation-time control is truly required
If an answer still sounds like "a more advanced class feature could handle it," revise it until you can say why the chosen owner is the clearest one.