liveBook · Manning

ICPO

As explained in Python Workout: 50 ten-minute exercises

A name-resolution order for locating attributes across an instance, its class, parent classes, and the object hierarchy.

ICPO names Python’s attribute lookup order: instance, class, parent classes, and finally object. When evaluating a.b, Python returns the first matching attribute it finds along that path. section 9.10

Use the lookup sequence to reason about methods, inheritance, and shared class attributes:

  • Instance: Python first checks the object itself, so an instance attribute can hide an attribute with the same name on its class. section 9.10 section 9.12
  • Class: if the instance lacks the attribute, Python checks its class. Methods such as str.upper are found on the class and called through the instance. section 9.10
  • Parents and object: if the class lacks the attribute, Python searches parent classes and ultimately the object hierarchy, making inherited behavior available without duplication. section 9.10 section 9.15
  • Dynamic class selection: referring to self.max_scoops lets one method use Bowl.max_scoops for Bowl instances and BigBowl.max_scoops for BigBowl instances. section 9.17

Inherited methods and overridden lookup

For `class Foo` with `x2` and `class Bar(Foo)` with `x3`, `b = Bar(10)` makes `b.x2()` find the method on Foo and `b.x3()` find it on Bar. Similarly, `s.upper()` finds `upper` on str after failing to find it on the string instance. A class attribute such as `Bowl.max_scoops` remains available through an instance, but assigning `one_bowl.max_scoops` creates an instance attribute that blocks the class value. When a subclass initializer must preserve parent setup, `super().__init__(name)` calls the parent initializer without naming the parent explicitly. section 9.10 section 9.12 section 9.15

class Foo():
    def __init__(self, x):
        self.x = x
    def x2(self):
        return self.x * 2
 

class Bar(Foo):
    def x3(self):
        return self.x * 3
 

b = Bar(10)
 
print(b.x2())     #1
print(b.x3())     #2

Runnable Foo and Bar code makes instance, class, and parent lookup visible through calls to inherited and subclass-specific methods. section 9.10

How Python Workout: 50 ten-minute exercises covers it

How deep it goes
Traces lookup from instance through class and parents to object, then applies it to shadowing, inheritance, and super without runtime internals.
Examples
Uses str.upper, Foo and Bar methods, Bowl.max_scoops, BigBowl overrides, and Employee calling Person.__init__.
What it assumes
Assumes familiarity with Python classes and instances while contrasting ICPO with the previously established LEGB variable lookup rule.
What you can do after
Diagnose/debug attribute results, predict inherited method calls, avoid accidental shadowing, and reuse methods across subclasses.
How it connects
Connects attribute lookup with classes, methods, inheritance, class attributes, instance attributes, super, and the LEGB rule.

Also explained in

Compare how 2 books explain ICPO →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Python Workout: 50 ten-minute exercises. The section links point to the parts of the book it draws on.