Foundations — Class vs object — blueprint vs instance
The parent note throws a lot of symbols at you at once: class, self, __init__, ., =, ==, f"...", is, type, Dog(...). If any of those looked like magic, this page rebuilds each one from the ground up so that when you re-read the parent, every line is obvious.
The mental picture we will keep returning to
Before symbols, the picture. A computer's memory is a long wall of numbered boxes. When you make an object, the computer reserves some of those boxes and writes your data into them. A name in your code (like d1) is just a label with an arrow pointing at those boxes.

Hold onto that image: names point, boxes store. Almost every symbol below is a way to either create boxes, reach into them, or ask which boxes a name points at.
Symbol 1 — the name and the = sign (assignment)
What it looks like: in the picture above, d1 = ... is the act of drawing the arrow from the label d1 to a box.
Why the topic needs it: the whole line d1 = Dog("Rex", 3) reads as "build a dog, then point the name d1 at it." Without understanding = as "point at", the idea that d1 and d2 are separate arrows to separate boxes never lands — and that separation is the entire point of the topic.
Edge case — aliasing (two names, one box)

Symbol 2 — the dot . (reach inside)

What it looks like: an arrow into the object's box, landing on one labelled slot inside it.
Why the topic needs it: d1.name, d1.age, d1.bark(), Dog.species — every single access in the parent note uses the dot. Once you see the dot as "reach inside the box the name points at", the difference between reaching into an object (d1.age) and reaching into a class (Dog.species) becomes visible geography, not memorised rules. See Memory model and references for where those boxes actually live.
Symbol 3 — class Name: (writing the blueprint)
What it looks like: the recipe card is an object pinned to the wall, holding the shared code and any class-level values — but no house has been built from it yet.
Why the topic needs it: this is the "blueprint" of the whole chapter's title. class Dog: pins the card; no instance exists until you build one.
Symbol 4 — Dog(...) with parentheses (instantiation)

What it looks like: the recipe card (class object) being used to stamp out a fresh house-box in memory, then an arrow handed back so a name can point at it.
Why the topic needs it: Dog (no parentheses) is the blueprint/class object; Dog("Rex", 3) (parentheses) builds an instance. This one visual difference — parentheses or not — is the line between "the card" and "a house". It flows straight into Constructors and __init__.
Symbol 5 — __init__ and self (filling the blank object)

What it looks like: during Dog("Rex", 3), self is a temporary arrow pointing at the new blank box, and self.name = name writes "Rex" into that box's name slot.
Why self and not just name? Because there are many objects. The code is written once (on the class), but must be able to say "write into whichever object is being built right now." self is the word that means "this one". Deep dive: self and instance methods.
Symbol 6 — class attribute vs instance attribute (two homes + lookup order)
What it looks like: species sits on the pinned card; name and age sit inside each individual house. Full treatment: Class vs instance attributes.
The lookup rule — object first, then class

Symbol 7 — f"..." (an f-string)
What it looks like: f"{self.name} says Woof!" with self.name being "Rex" becomes the finished text "Rex says Woof!".
Why the topic needs it: the bark method uses it to show that behaviour reads instance data. The same code produces different text for d1 and d2 because self.name differs. It is the payoff of "shared code, separate data".
Symbol 8 — is, ==, and type(...) (identity vs equality)
What it looks like: a is b compares the arrowheads' destinations; a == b peers inside the boxes to compare their written contents. Two houses built from identical plans with identical paint are still two different houses at two different addresses — so a is b is False, and a == b is also False for a plain class until you define equality.
Why the topic needs it: this defeats the classic trap "equal-looking data means same object." Identity is about address (is), equality is about contents (==) — the parent's Example 3 lives entirely on this distinction.
How the foundations feed the topic
Read the map bottom-up, and tie each node to a concrete moment you have now seen:
- Memory boxes and names → the wall of boxes in figure s01.
- Assignment (point a name) →
d1 = ...drawing an arrow, and the aliasing trapb = a(figure s05) where two arrows share one box. - The dot (reach inside) →
d1.agereaching into a slot (figure s02). class(the card) → one class object, zero instances — figure s03's pinned card.- Parentheses (build one) →
Dog("Rex",3)stamping a house (figure s03). __init__andself→selfwriting "Rex" into the new box (figure s04), and__init__returningNone.- Class vs instance attributes + lookup order → object-first search and shadowing (figure s06).
- f-string →
barkreading instance data at run-time. is/==/type→ identity vs equality, the whole point of "two dogs, same data, different boxes."
This links back to the parent 2.1.01 Class vs object — blueprint vs instance (Hinglish) and forward to Encapsulation.
Equipment checklist
In code, what does = actually command?
After b = a, what happened to the object?
b is a second arrow to the same box (an alias), so mutating through one name is seen through the other.What does the dot . do in d1.age?
d1 points at and fetch the part named age from inside it.Does class Dog: create any object?
Dog(...).What is the difference between Dog and Dog(...)?
Dog is the class object/blueprint; Dog(...) instantiates — builds a fresh instance and returns a reference to it.What does self refer to during setup?
self to it automatically).What must __init__ return?
In what order does Python look up d1.species?
When are an f-string's {...} slots evaluated, and how do you print a literal {?
{{ to print a literal {.What question does a is b ask versus a == b?
is asks "same box in memory" (identity); == asks "equal contents" (equality), which defaults to identity for a plain class until you define it.What does type(a) give back?
a was built from.