PYTHON / CHAPTER 12

Instance state and behavioral contracts

Intermediate

Protect 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.

Python example
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)
Result
['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 challenges

CHECK YOUR UNDERSTANDING

Chapter checkpoint

Where should an independent history list be initialized?