2.1.4 · D1OOP Fundamentals

Foundations — Instance methods, class methods (`@classmethod`), static methods (`@staticmethod`)

2,248 words10 min readBack to topic

Before you can understand why self, cls, and "nothing" appear, you must be fluent in the small pile of words and symbols the parent note leans on without stopping to explain. This page builds every one of them from the ground up, in the order they depend on each other.


0. class — the blueprint

Picture a cookie cutter. The cutter is not a cookie — you can't eat it — but every cookie you stamp out has the shape the cutter defines.

Figure — Instance methods, class methods (`@classmethod`), static methods (`@staticmethod`)

Look at the figure: the violet shape on the left is the class (the cutter). The three orange shapes on the right are objects stamped from it. The class holds the plan; the objects are the real things.

Related vault note: OOP Fundamentals - Classes and Objects.


1. Object / instance — the stamped-out thing

In the figure above, each orange cookie is one instance of the violet cutter. If the cutter is Circle, then a circle of radius 2 is an instance of Circle.


2. . (the dot) — "reach inside and get"

Read c.area out loud as "c's area". The dot is a little arrow that walks into the thing on its left and picks out the name on its right.


3. Attribute — a name that belongs to something

There are two homes an attribute can live in:

Figure — Instance methods, class methods (`@classmethod`), static methods (`@staticmethod`)

In the figure, the shared value PI (magenta) sits on the class and every object points up to it. But each object carries its own r (orange) locally.

Deeper dive available at Instance vs Class attributes.


4. Function vs method — a function with a home

Figure — Instance methods, class methods (`@classmethod`), static methods (`@staticmethod`)

The figure shows a plain function floating free (left) versus the same function placed inside a class box (right). The code is identical; the only change is its address. That address is what lets Python attach the automatic first argument.


5. Parameter, argument, and the "first slot"

The word positional matters here:


6. Decorator — the @ wrapper

Think of it as a stamp on an envelope that tells the post office (Python) how to handle the letter (the function) — express, standard, or return-to-sender — before it's ever opened.

Full treatment: Decorators.


7. __init__, __dict__, dunder names

  • __init__ runs once when an object is born, to set up its instance attributes (this is where self.r = r lives).
  • __dict__ is the actual storage drawer — a dictionary mapping attribute names to their values. Circle.__dict__['f'] is literally where the function f is kept.

8. Descriptor & __get__ — where self is born

This is the deepest prerequisite, so we build it slowly.

Here is the key secret the parent uses:

Figure — Instance methods, class methods (`@classmethod`), static methods (`@staticmethod`)

Walk the figure left to right: you type a.f → the dot triggers __get__ → out pops a bound method that already holds a → you add () → Python calls A.f(a), so self = a. No magic keyword — just a descriptor doing its job.

Go deeper at Descriptors and the __get__ protocol.


9. type(a) — "what class made this?"

In the figure of section 8, type(a) is the arrow pointing from a cookie back up to its cutter.


10. Inheritance & subclass — a preview

Related: Inheritance and method resolution order (MRO) and Factory design pattern.


The prerequisite map

class = blueprint

object = instance

dot operator a.b

attribute

instance attribute self.r

class attribute PI

function vs method

parameter and first positional slot

descriptor and __get__

self = object injected

decorator @

classmethod injects class

staticmethod injects nothing

type of a

subclass inheritance

THE TOPIC: three method kinds

Read the map top-down: blueprints give objects and the dot; the dot plus functions give the descriptor mechanism; the descriptor injects self; decorators swap the injection to give cls or nothing. All arrows converge on the topic.


Equipment checklist

Cover the right side and answer each. If any stalls you, re-read that section before the main note.

What is the difference between a class and an object?
The class is the blueprint (cookie cutter); the object is one concrete thing stamped from it (a cookie).
What does the dot in c.area actually do?
It reaches into c and fetches the attribute named area — and for methods it triggers the descriptor's __get__, not a raw lookup.
Where does an instance attribute live vs a class attribute?
Instance attribute lives on one object (self.r); class attribute lives on the shared blueprint (PI) and every object sees it.
What is the difference between a function and a method?
A method is just a function stored inside a class — same code, different home.
What is a positional argument and why does it matter here?
A value filled by its place in line; Python auto-fills the first positional slot of a method with the object, class, or nothing.
What does a decorator like @classmethod do?
It wraps the function to change its behaviour — here, to change what fills the first argument slot.
What is __dict__?
The storage drawer of a class or object — a dictionary mapping attribute names to their values.
What is a descriptor, and why are functions descriptors?
A descriptor is any object with a __get__; functions have one, so a.f returns a bound method carrying a, which becomes self.
Rewrite a.f() as the explicit call it becomes.
A.f(a) — the object a is slipped in as the first argument.
Why is cls the class and not the object?
Because @classmethod's __get__ injects type(a) (the class), so subclass calls yield subclass instances.