Classes
A class is a blueprint; an instance (or object) is a concrete thing built from that blueprint, with its own independent state.
class Dog: def __init__(self, name: str): self.name = name self.tricks: list[str] = []
def learn_trick(self, trick: str) -> None: self.tricks.append(trick)
rex = Dog("Rex")rex.learn_trick("sit")
fido = Dog("Fido")print(rex.tricks) # ['sit']print(fido.tricks) # [] — completely separate state__init__ (highlighted, line 2) is the constructor — it runs once per instance and sets up that
instance’s own attributes. learn_trick (line 6) is an instance method: the first parameter,
self, is always a reference to the specific object the method was called on.
Classes exist in other languages too
The shape is the same everywhere: a constructor, instance state, instance methods.
class Dog: def __init__(self, name: str): self.name = name
def bark(self) -> str: return f"{self.name} says woof!"public class Dog { private final String name;
public Dog(String name) { this.name = name; }
public String bark() { return name + " says woof!"; }}Class attributes vs. instance attributes
class Dog: species = "Canis familiaris" # class attribute — shared by every instance
def __init__(self, name: str): self.name = name # instance attribute — unique per instance
print(Dog("Rex").species) # "Canis familiaris"print(Dog("Fido").species) # "Canis familiaris" — same value, shared on the classMutable class attributes (lists, dicts) are a classic gotcha: since they’re shared, mutating one
through an instance affects every instance. Prefer setting mutable defaults inside __init__.
Where this leads
Classes are the foundation for the rest of Python OOP — inheritance, @property, dunder methods,
and dataclasses all build directly on the instance/class-attribute model shown here.