Python Object-Oriented Programming (OOP) Tracing
Object-Oriented Programming (`OOP`) organizes state and behavior into reusable class blueprints. Tracing class vs instance attributes (`self.var vs Class.var`), method overriding (`super()`), and C3 Method Resolution Order (`MRO`) is standard in senior coding interviews.
Core Conceptual Insights
Theoretical Blueprint:A class is like an architectural blueprint for an apartment building, while `self` refers to one specific physical apartment unit built from that blueprint. Modifying a shared blueprint (`Class.attribute`) affects all future references, but modifying your own apartment walls (`self.attribute`) affects only your unit.
Common Developer Trap:Many developers incorrectly assume `super().__init__()` runs automatically when a subclass defines its own `__init__`. In Python, you must explicitly invoke `super().__init__()` or the parent constructor is skipped entirely!
Structured Practice Breakdown
Class vs instance attribute shadowing
class Node:
count = 0
def __init__(self):
Node.count += 1
self.count = 100
n1 = Node()
n2 = Node()
print(Node.count, n1.count)2 100Execution Walkthrough
Creating `n1` and `n2` increments `Node.count` twice (`2`). Each instance gets its own `self.count = 100`. Output: `2 100`.
`super()` cooperative method resolution (`MRO`)
class A:
def ping(self): return 'A'
class B(A):
def ping(self): return super().ping() + 'B'
class C(A):
def ping(self): return super().ping() + 'C'
class D(B, C): pass
print(D().ping())ACBExecution Walkthrough
`D().ping()` calls `B.ping() -> C.ping() -> A.ping() -> 'A'`. Then C appends `'C'` (`'AC'`), and B appends `'B'` (`'ACB'`). Output: `ACB`.
Private name mangling (`__attribute`)
class Account:
def __init__(self, balance):
self.__balance = balance
acc = Account(500)
try:
print(acc.__balance)
except AttributeError:
print(acc._Account__balance)500Execution Walkthrough
Python transforms `self.__balance` into `_Account__balance`. Direct lookup fails (`AttributeError`), and the exception handler successfully accesses `acc._Account__balance -> 500`.
`@classmethod` vs `@staticmethod` binding
class MathTool:
factor = 10
@classmethod
def scale(cls, val):
return val * cls.factor
@staticmethod
def add(a, b):
return a + b
print(MathTool.scale(3), MathTool.add(2, 4))30 6Execution Walkthrough
`MathTool.scale(3)` returns `3 * 10 = 30`. `MathTool.add(2, 4)` returns `2 + 4 = 6`. Output: `30 6`.