PyCodeItPython trace & interview prep
Python Mastery Hub/oop foundations
Python 3.12+ CPython TrackPyodide WASM Sandbox

OOP Foundations & Object Lifecycle

Master object creation hooks, memory layout, descriptor protocols, dunder method mechanics, and attribute resolution edge cases.

Theoretical Mechanics & Memory Architecture

Python's object-oriented architecture is dynamic, introspective, and descriptor-driven. Classes and instances are heap objects backed by namespace dictionaries (__dict__). Attribute lookups, inheritance traversal, and method bindings are strictly orchestrated by the C3 Linearization algorithm (Method Resolution Order, or MRO) and the Descriptor Protocol (__get__, __set__, __delete__).

Attribute Resolution Sequence & Descriptor Protocol

When evaluating instance.attr, CPython executes a deterministic lookup hierarchy: (1) Data descriptors on the class defining __set__ or __delete__, (2) The instance's own __dict__, (3) Non-data descriptors on the class (such as methods or property getters), (4) Standard class attributes, (5) Base classes according to MRO, and (6) Fallback to __getattr__.

Mutable Class Attributes Shared Across All Instances

Defining a mutable container at class scope (such as class Team: members = []) binds a single shared list to the class object in memory. Any instance appending to self.members mutates state across all instances. Mutable attributes must always be instantiated per instance inside __init__ via self.members = [].

Interactive Dry-Run Execution Workspace

Problem 1 / 59+50 XP

__new__ Returning Existing Instance Bypasses __init__?

hard
Task: Output Execution Prediction

Trace CPython execution step-by-step and deduce the exact stdout string emitted by this snippet.

Socratic Guidance-5 XP penalty per revealed hint
Topic Problems0 / 59 Solved
main.pyCPython 3.12 (WASM)
1
2
3
4
5
6
7
8
9
10
11
12
class Singleton:
    _inst = None
    def __new__(cls, val):
        if cls._inst is None:
            cls._inst = super().__new__(cls)
        return cls._inst
    def __init__(self, val):
        self.val = val

a = Singleton(1)
b = Singleton(2)
print(a.val, b.val, a is b)
Press Enter to submit
Match exact whitespace and capitalization

Frequently Asked Questions on OOP Foundations & Object Lifecycle

Why do mutable class attributes cause unexpected cross-instance state pollution?

Class attributes are evaluated once when the class definition executes and reside in the class __dict__. When an instance accesses self.attr without rebinding it, Python resolves to the shared class attribute. In-place mutations modify the shared class instance.

How does the C3 Linearization algorithm determine Method Resolution Order in multiple inheritance?

C3 Linearization guarantees two invariants: child classes precede parent classes, and the order of base classes in the class declaration is strictly preserved. It computes a monotonic merge of parent MROs, raising TypeError if an inconsistent hierarchy is declared.

How does declaring __slots__ optimize memory consumption in Python classes?

__slots__ instructs CPython to allocate a fixed-size array of descriptor pointers directly on the instance struct, bypassing the creation of a dynamic __dict__ for each instance. This saves hundreds of bytes per object in large-scale deployments.