Defining Your Own Classes
Objects follow a predictable lifecycle: construction (via __init__), operation (via method calls that modify state), and destruction (via __del__).
From Creation to Cleanup
An object-oriented program becomes easier to understand when you follow an object's lifecycle. The central pattern has three phases: construction, operation, and destruction. During construction, __init__ sets up the object's internal data attributes. During operation, methods are called with dot notation and may change the object's internal state. During destruction, Python calls __del__ to clean up the object.
Construction with __init__
The constructor is named __init__. Python calls it automatically when you create an object. Its role is to set up the object's internal data attributes, giving the object the initial structure it needs before methods operate on it.
class Counter: def __init__(self): self.value = 0 counter = Counter()
Methods and State Changes
Methods are functions that belong to objects. They are called with dot notation, such as object.method(). A method can modify the object's internal state, so the same object can contain different values after successive operations.
Tracing Two Method Calls
Determine how the internal value changes in the Counter example.
Create the object: Counter() invokes __init__, which sets value to 0.
First increment: counter.increment() invokes the method, which changes value from 0 to 1.
Second increment: The same method changes the same object's value from 1 to 2.
After the two method calls, the object's internal value is 2.
The important point is that counter.increment() is not just a label for an action. Python looks up the increment method on counter, calls it, and allows that method to modify the object's internal state.
Bracket Access and __getitem__
Square bracket access is another form of method invocation. For an object named stuff, the expression stuff[0] is shorthand for stuff.__getitem__(0). The source also identifies list.__getitem__(stuff, 0) as an equivalent form. In each form, the object is accessed with the key or index 0.
| Written form | Underlying form |
|---|---|
| stuff[0] | stuff.__getitem__(0) |
| stuff.__getitem__(0) | direct call to the object's __getitem__ method |
| list.__getitem__(stuff, 0) | equivalent list method form |
The three equivalent forms identified in the source
In the example, item_a, item_b, and item_c each refer to the item selected with index 0.Reading Each Line Mechanically
When reading object-oriented code, replace surface syntax with the mechanism it represents. Creating list() invokes construction and automatic initialization. Calling stuff.append('item') looks up the append method on stuff and calls it with the supplied parameter; the method changes the list's internal state. Reading stuff[0] means recognizing the shorthand call to __getitem__(0). When the object is no longer needed at program end, Python calls __del__ for cleanup.
A Complete Trace
Map each operation in a short list example to its underlying mechanism.
stuff = list(): A list object is created, and its constructor initializes the object's internal structure.
stuff.append('item'): Python looks up append on stuff, calls it with item, and the method modifies the list's internal state.
stuff[0]: The bracket expression is shorthand for stuff.__getitem__(0), which accesses the item at index 0.
Program completion: When stuff is no longer needed at the end of the program, Python calls __del__ to perform cleanup.
The visible syntax is a compact way to express construction, method-based state changes, item access, and destruction.
What do you think happens?
What mechanism does stuff[0] represent?
Reveal answer
Answer: A shorthand call to stuff.__getitem__(0)
Square bracket syntax is defined as a shorthand for calling the object's __getitem__ method with the supplied key or index.
Mistakes in Lifecycle Tracing
Treating __init__ as an ordinary method that must be called manually after every object is created
The constructor is called automatically when the object is created.
Fix:
Read the creation expression as the event that invokes __init__.Assuming a method call only produces an action and does not change the object
Methods can modify the object's internal state.
Fix:
Record the object's state before and after each method call.Thinking stuff[0] is unrelated to __getitem__
Square bracket syntax is a shorthand for stuff.__getitem__(0).
Fix:
Translate bracket access into the corresponding __getitem__ call while tracing.Stopping the lifecycle trace after the final visible operation
The lifecycle also includes destruction, during which Python calls __del__ when the object is no longer needed.
Fix:
Include cleanup as the final phase of the lifecycle.
For each expression below, name the underlying mechanism it invokes: creating an object with list(), changing it with append(), and accessing an item with [0]. Then place those operations in the construction, operation, or destruction phase.
Hints
- Creation invokes the constructor and initialization.
- A method call can modify internal state.
- Bracket access maps to __getitem__.
Lifecycle Checklist
- Object construction automatically invokes __init__, which sets up internal data attributes.
- Methods belong to objects, are called with dot notation, and can modify internal state.
- Square bracket syntax such as stuff[0] is shorthand for stuff.__getitem__(0).
- A complete trace includes construction, operation, and destruction.
- When an object is no longer needed at program completion, Python calls __del__ for cleanup.
Key Takeaways
- An object follows a lifecycle of construction, operation, and destruction.
- __init__ is called automatically during object creation to establish internal data attributes.
- Method calls made with dot notation can change the object's internal state.
- stuff[0], stuff.__getitem__(0), and list.__getitem__(stuff, 0) are equivalent forms identified in the source.
- To understand object-oriented code, map each visible expression to the mechanism it invokes.