Most people learning Python get stuck on “classes” at some point. When first encountering them, many feel, “This is so abstract, like the legendary programming black magic?” 😵
Don’t panic; classes are not that mysterious. You can think of them as common “molds” or “templates” in life. Just like a tailor needs a template to cut and sew fabric, a class is that template, and the clothes are the “objects” made based on that template.
Today, we will discuss Python classes from start to finish, without any fancy metaphysics, breaking it down and explaining it thoroughly, so that by the end, you can say, “Oh, so that’s how it works!”

1. Classes and Objects: Starting with Real-Life Examples
Suppose you have a cat at home named Mimi, who is 2 years old. How would you record this in code?
Let’s start with the most straightforward approach:
class Cat:
def __init__(self, name, age):
self.name = name # Attribute: Name
self.age = age # Attribute: Age
# Creating an object based on the class
my_cat = Cat("Mimi", 2)
print(my_cat.name) # Output: Mimi
print(my_cat.age) # Output: 2
See?
<span>Cat</span>is the mold.<span>Mimi</span>is the object created using that mold.
Just remember this phrase: Classes are templates, and objects are the finished products..
2. The Simplest Class: Even an Empty Shell Can Run
In Python, the keyword for creating a class is <span>class</span>. By convention, class names use PascalCase, such as <span>Person</span>, not <span>person</span>.
Here’s the simplest example:
class Person:
pass # An empty class that does nothing
person1 = Person()
print(person1) # Output: <__main__.Person object at 0x00000……>
The <span>pass</span> here is just a placeholder. Writing it indicates, “I will leave this empty for now and fill it in later.”
This kind of writing is common in projects, usually to set up a framework first and then add logic later.
3. Constructor: Giving Objects Attributes at Birth
Once you have a class, you definitely want the object to come with some data upon creation. For example, a dog’s name and breed require a constructor — <span>__init__</span>.
class Dog:
def __init__(self, name, breed):
self.name = name # Attribute: Pet Name
self.breed = breed # Attribute: Breed
my_dog = Dog("Buddy", "Golden Retriever")
print(my_dog.name) # Output: Buddy
print(my_dog.breed) # Output: Golden Retriever
<span>__init__</span> is automatically executed when the object is created, and you don’t need to call it manually. It’s like when a child is born; you don’t need to say, “Give him a name,” the doctor will write it on the birth certificate.
Note: You cannot use <span>return</span> to return a value in the constructor; otherwise, Python will throw an error.
4. Self: The “ID Card” of the Class
Many beginners get confused by <span>self</span>. It is simply a reference that points to “the current object”.
For example:
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
print(f"{self.name} says Woof!")
def birthday(self):
self.age += 1
print(f"Happy Birthday, {self.name}! Now you are {self.age} years old.")
my_dog = Dog("Buddy", 3)
my_dog.bark() # Output: Buddy says Woof!
my_dog.birthday() # Output: Happy Birthday, Buddy! Now you are 4 years old.
When you write <span>my_dog.bark()</span>, Python automatically passes <span>my_dog</span> to the <span>self</span> in the method. So, <span>self.name</span> is equivalent to <span>my_dog.name</span>.
In simple terms: <span>self</span> is the object’s ID card, proving “this is me”.
5. Attributes and Methods: Objects Can “Carry Things” and “Do Things”
In a class:
- Attributes = Data, such as a person’s name and age.
- Methods = Actions, such as “run” or “bark”.
class Circle:
def __init__(self, radius):
self.radius = radius # Attribute: Radius
def area(self):
return 3.14 * self.radius ** 2 # Method: Returns area
my_circle = Circle(5)
print(my_circle.area()) # Output: 78.5
Isn’t it similar to real life? You have attributes (height, weight) and can perform actions (run, eat, sleep).
6. Class Attributes: The “Last Name” Shared by the Family
Sometimes, certain attributes are not unique to an instance but are common to the entire class. For example, all dogs belong to the “Canidae” family. This is called a class attribute.
class Dog:
species = "Canidae" # Class attribute
def __init__(self, name):
self.name = name # Instance attribute
dog1 = Dog("Buddy")
dog2 = Dog("Max")
print(dog1.species) # Output: Canidae
print(dog2.species) # Output: Canidae
Dog.species = "Felidae"
print(dog1.species) # Output: Felidae
print(dog2.species) # Output: Felidae
Tip: It’s recommended to access class attributes using the class name, such as <span>Dog.species</span>, for clarity.
7. Three Types of Methods: Instance, Class, and Static
Python methods are divided into three categories, each serving different purposes:
-
Instance Methods (most commonly used): Operate on the object’s data.
class Cat: def __init__(self, name): self.name = name def greet(self): return f"Meow! I am {self.name}." cat = Cat("Mimi") print(cat.greet()) # Output: Meow! I am Mimi. -
Class Methods: Operate on class data, declared with
<span>@classmethod</span>.class Dog: species = "Canidae" @classmethod def change_species(cls, new_species): cls.species = new_species Dog.change_species("Felidae") print(Dog.species) # Output: Felidae -
Static Methods: Independent functions unrelated to the class or object, declared with
<span>@staticmethod</span>.class Math: @staticmethod def add(a, b): return a + b print(Math.add(3, 5)) # Output: 8
Remember this mnemonic: Instance methods manage themselves, class methods manage the family, and static methods manage the outside world.
8. Special Methods: Making Objects More “Pythonic”
Python has a bunch of methods that start and end with double underscores, helping you customize class behavior.
str and repr
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return f"Person(name={self.name}, age={self.age})"
def __repr__(self):
return f"<Person {self.name} ({self.age} years old)>"
p = Person("Alice", 30)
print(str(p)) # Output: Person(name=Alice, age=30)
print(repr(p)) # Output: <Person Alice (30 years old)>
One is for the user (<span>__str__</span>), and the other is for the developer (<span>__repr__</span>).
eq
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __eq__(self, other):
return self.x == other.x and self.y == other.y
p1 = Point(1, 2)
p2 = Point(1, 2)
print(p1 == p2) # Output: True
9. Inheritance and Polymorphism: Write Once, Reuse Everywhere
The most powerful aspect of writing classes is inheritance. Subclasses can inherit methods from parent classes and also override them.
class Animal:
def speak(self):
raise NotImplementedError("Subclasses must implement this method.")
class Dog(Animal):
def speak(self):
return "Woof!"
class Cat(Animal):
def speak(self):
return "Meow!"
animals = [Dog(), Cat()]
for animal in animals:
print(animal.speak())
Inheritance allows code reuse; polymorphism makes “the same interface, different implementations” possible.
10. Mastering Classes is the Key to Entering Python
Classes may seem convoluted, but once you understand them, you’ll find they simply bring the real world into code.
- You have attributes (name, age);
- You have methods (eating, sleeping, studying);
- You also have inheritance (genes from parents 😄).
Mastering classes allows you to write clearer and more extensible code. This is a crucial step from beginner to advanced.
Don’t be afraid of their complexity; practice with a few examples, and you’ll find: Classes are not a barrier, but a tool to help you go further.