PYTHON / CHAPTER 12
Instance state and behavioral contracts
IntermediateProtect object invariants and avoid shared class-level collections.
By the end of this chapter
- Initialize mutable state per instance
- Use methods to validate changes
- Distinguish an instance attribute from a class attribute
The idea
A class can group state with the operations permitted on it. __init__ initializes a new instance, and methods receive that instance as self. Put per-instance mutable collections inside __init__. A list placed directly in the class body is shared until an instance shadows that attribute, which often surprises developers expecting each object to have a private list.
Methods should enforce the rules that make the object meaningful. A reservation must validate its amount and available capacity before decreasing the remaining count. A leading underscore is a convention for internal implementation, not a security boundary. Properties can expose a controlled interface, but callers and tests should still exercise invalid inputs and verify that failure leaves the object unchanged.
class Basket:
def __init__(self):
self.items = []
def add(self, item):
self.items.append(item)
a, b = Basket(), Basket()
a.add("pear")
print(a.items, b.items)['pear'] []
Each constructor call creates a fresh items list.
Try it yourself
Implement a capacity object whose reserve method rejects negative or excessive requests without changing state.
Use your own editor for this exercise. Runnable challenges on CodeQuest are available for JavaScript, Python, and SQL.
Open Python coding challengesCHECK YOUR UNDERSTANDING