Menu

Earn Premium with Referrals

Invite your friends and earn Premium rewards through our referral program.

See how it works and start inviting friends.

Part 3: OOP & Magic Methods
PYTHON

Part 3: OOP & Magic Methods

Review Python classes, inheritance, MRO, properties, magic methods, and class versus instance attributes.

1. Class & instance attributes

  • Class attribute — defined in the class body; shared by all instances.
  • Instance attribute — set on self; belongs to one object.
  • Shadowing: reading self.name finds the instance attr first; setting self.name never mutates the class attr (creates a new instance attr).
class Car:
    wheels = 4          # class attr, shared

c1, c2 = Car(), Car()
print(c1.wheels, c2.wheels)   # 4 4
c1.wheels = 6          # creates new instance attr on c1 only
print(c1.wheels, c2.wheels, Car.wheels)  # 6 4 4

2. Constructors & self

  • __init__ is the initializer (not the constructor — that’s __new__).
  • __new__ creates the instance (used for singletons, immutable types); __init__ sets it up.
  • self is the conventional name for the instance; methods receive it explicitly.
  • Classmethods (@classmethod, receive cls) and staticmethods (@staticmethod, no automatic first arg) differ.

3. Inheritance & MRO

  • Single inheritance + mixins are idiomatic; multiple inheritance forces an MRO.
  • MRO (Method Resolution Order) in Python 3 = C3 linearization; inspect with Class.__mro__.
  • A method lookup walks MRO left-to-right, depth-first, then superclasses — the first match wins.
  • super() is not “the parent class” — it’s a proxy that follows the MRO after self’s class. It makes cooperative diamond inheritance work.
class A: ...
class B(A): ...
class C(A): ...
class D(B, C): ...
print(D.__mro__)   # D → B → C → A → object
  • Diamond: with cooperative super(), each ancestor’s method runs exactly once.

4. Abstract classes

  • Via abc.ABC + @abstractmethod.
  • An abstract class cannot be instantiated; subclasses must implement abstract methods.
  • Interface-like contracts are expressed with ABCs + @abstractmethod.
from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self): ...

5. Properties & encapsulation

  • Python has no private keyword — name mangling _name is convention.
  • __name (double underscore) inside a class triggers name mangling_ClassName__name, discouraging accidental access (not real security).
  • @property turns a method into an attribute-like accessor; getter/setter/deleter.
class Temp:
    def __init__(self): self._c = 0
    @property
    def celsius(self): return self._c
    @celsius.setter
    def celsius(self, v): self._c = v

6. Magic methods cheat-sheet

CategoryMethods
Init__new__, __init__, __del__
Represent__repr__ (dev), __str__ (user)
Equality__eq__, __ne__, __lt__, __le__, __gt__, __ge__, __hash__
Containers__len__, __getitem__, __setitem__, __contains__, __iter__
Context__enter__, __exit__ (context manager)
Callable__call__
Arithmetic__add__, __sub__, __mul__, … reflected __radd__
  • __eq__ and __hash__: defining __eq__ sets __hash__ to None → the object becomes unhashable unless you re-implement __hash__. Classic interview point.
  • __str__ vs __repr__: print() uses __str__; interpreter/repr() uses __repr__; fall back to each other.

7. Interview checkpoint

  • Class vs instance attribute shadowing.
  • MRO + diamond — why C3 and super() matter.
  • __eq__/__hash__ coupling (objects as dict keys).
  • @property, dataclasses (@dataclass auto-generates __init__, __repr__, __eq__).
  • is vs == in OOP (identity vs semantic equality).

My Private Notes

Notes are auto-saved locally to this device.