Skip to content

What Are Classes and Objects in Python? Simple Explanation for Beginners

The Problem: Classes Feel Weird

When I started learning Python, I could understand functions, loops, and boolean logic. But when I reached classes and objects, everything felt confusing.

I saw code like this:

class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def greet(self):
print(f"Hi, I'm {self.name}")

I had so many questions:

  • What is __init__?
  • Why do I need self everywhere?
  • Is a class the same as an object?
  • When should I use classes instead of functions?

If you feel the same way, I get it. Classes feel weird because they require a different way of thinking. You go from “do this, then that” to “create things with properties and behaviors.”

What Are Classes and Objects?

Let me explain with a simple analogy.

A class is like a cookie cutter. It defines the shape and pattern.

An object is like an actual cookie made from that cutter. You can make many cookies from one cutter, and each cookie can have different decorations (sprinkles, chocolate chips), but they all have the same basic shape.

Another way to think about it:

  • Class = Blueprint for a house
  • Object = The actual house built from that blueprint

You can build 100 houses from one blueprint. Each house (object) is different—different paint color, different furniture—but they all follow the same structure (class).

In Python:

# Class is the blueprint
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
# Objects are instances built from the blueprint
person1 = Person("Alice", 25) # First object
person2 = Person("Bob", 30) # Second object

Class vs Object: The Difference

I think the confusion comes from not seeing the difference clearly.

Class = Template with:

  • Attributes (data/variables) - what it HAS
  • Methods (functions) - what it DOES

Object = Specific instance with actual values for those attributes.

Let me show you a video game example:

# Class: Character blueprint
class Character:
def __init__(self, name, health, strength):
self.name = name # This character's name
self.health = health # This character's health
self.strength = strength # This character's strength
def attack(self, target):
damage = self.strength * 2
target.health -= damage
print(f"{self.name} attacks {target.name} for {damage} damage!")
def is_alive(self):
return self.health > 0
# Create objects (actual characters)
warrior = Character("Warrior", health=100, strength=15)
mage = Character("Mage", health=60, strength=25)
# Each object has its own data
print(warrior.health) # 100
print(mage.health) # 60
# Objects can interact
warrior.attack(mage) # "Warrior attacks Mage for 30 damage!"
print(mage.health) # 30
mage.attack(warrior) # "Mage attacks Warrior for 50 damage!"
print(warrior.health) # 50

See? The Character class just defines WHAT a character is. The warrior and mage objects are the ACTUAL characters with specific values.

Understanding the Syntax

When I first saw classes, the syntax confused me. Let me break it down.

__init__ - The Setup Method

class Person:
def __init__(self, name, age): # Runs automatically
self.name = name
self.age = age

__init__ is a special method. It runs automatically when you create an object. Think of it as the “setup” phase.

person = Person("Alice", 25) # __init__ runs here

When that line runs, Python calls __init__ with:

  • self = the new object being created
  • name = “Alice”
  • age = 25

self - This Specific Object

I found self confusing at first. Here’s how I think about it now.

self just means “THIS specific object I’m working with.”

class Person:
def __init__(self, name):
self.name = name # THIS object's name
def greet(self):
print(f"Hi, I'm {self.name}") # Use THIS object's name

When you create multiple objects, self keeps track of which one you’re using:

person1 = Person("Alice")
person2 = Person("Bob")
person1.greet() # self refers to person1, prints "Hi, I'm Alice"
person2.greet() # self refers to person2, prints "Hi, I'm Bob"

Think of self like saying “MY” vs “THE”:

  • self.name = “MY name” (this object’s name)
  • Without self, Python wouldn’t know WHICH object’s name you mean

Methods - Functions Inside Classes

class Person:
def __init__(self, name):
self.name = name
def greet(self): # This is a method
print(f"Hi, I'm {self.name}")

Methods are just functions inside a class. The only difference is they always take self as the first parameter.

Classes vs Functions: When to Use Which

I used to wonder when I should use a class instead of just functions.

Use functions for:

  • Simple, one-off tasks
  • Actions that don’t need to remember data

Use classes for:

  • Multiple things with the same structure
  • When you need to group data AND behavior together

Let me show you what I mean.

Without Classes (Using Functions)

# Scattered variables
person1_name = "Alice"
person1_age = 25
person1_job = "engineer"
person2_name = "Bob"
person2_age = 30
person2_job = "designer"
def greet_person(name, age, job):
print(f"Hi, I'm {name}, {age} years old, and I work as a {job}")
def promote_person(name, job, new_title):
print(f"{name} is now promoted to {new_title}!")
# Call functions with all the data
greet_person(person1_name, person1_age, person1_job)
promote_person(person1_name, person1_job, "Senior Engineer")
greet_person(person2_name, person2_age, person2_job)

This works, but see the problem? The data (name, age, job) and the behavior (greet, promote) are separate. You have to pass everything around manually.

With Classes

# Data and behavior together
class Person:
def __init__(self, name, age, job):
self.name = name
self.age = age
self.job = job
def greet(self):
print(f"Hi, I'm {self.name}, {self.age} years old, and I work as a {self.job}")
def promote(self, new_title):
print(f"{self.name} is now promoted to {new_title}!")
self.job = new_title
# Create objects
person1 = Person("Alice", 25, "engineer")
person2 = Person("Bob", 30, "designer")
# Each object knows its own data
person1.greet()
person1.promote("Senior Engineer")
person2.greet()

Now the data stays with the object. The object knows its own name, age, and job. You don’t have to pass everything around.

Why This Matters

I think classes are worth learning because they help you:

  1. Organize code: Group related data and functions together
  2. Reuse logic: Create multiple objects from one template
  3. Model reality: Represent real-world things (Users, Products, Orders)
  4. Scale: Build large applications without spaghetti code

Imagine building a game with 100 characters. Without classes, you’d need 100 separate variables for names, 100 for health, 100 for strength. With classes, you create one Character class and make 100 objects.

Common Beginner Mistakes

I made these mistakes when I started. Maybe you will too.

Forgetting self

class Person:
def __init__(self, name):
self.name = name # CORRECT
def greet(self):
print(f"Hi, I'm {name}") # WRONG! Missing self.name

The method needs self.name, not just name. Python doesn’t know which object’s name you mean.

Confusing Class and Object

class Person:
def __init__(self, name):
self.name = name
Person.greet() # WRONG! Person is the blueprint, not an actual object
alice = Person("Alice") # CORRECT! Create an object first
alice.greet()

The class is just the template. You need to create objects (instances) from it.

Overusing Classes

# Don't do this - too simple for a class
class Adder:
def add(self, a, b):
return a + b
# Just use a function instead
def add(a, b):
return a + b

Not everything needs to be a class. If you have a simple task without data to remember, a function is fine.

Practice Exercise

The best way to understand classes is to write code. Let me give you an exercise.

Task: Create a Dog class with:

  • Attributes: name, breed
  • Methods: bark(), info()

Try it yourself before looking at my solution.

# Your turn! Write the Dog class here

My Solution

class Dog:
def __init__(self, name, breed):
self.name = name
self.breed = breed
def bark(self):
print(f"{self.name} says: Woof!")
def info(self):
print(f"{self.name} is a {self.breed}")
# Create some dogs
dog1 = Dog("Buddy", "Golden Retriever")
dog2 = Dog("Max", "German Shepherd")
dog1.bark() # "Buddy says: Woof!"
dog1.info() # "Buddy is a Golden Retriever"
dog2.bark() # "Max says: Woof!"
dog2.info() # "Max is a German Shepherd"

Summary

In this post, I explained what classes and objects are in Python. The key point is that classes are blueprints (templates) that define what something is and what it can do, while objects are specific instances created from those blueprints.

If you understand functions, you can understand classes. Just think of classes as groups of related data (variables) and functions (methods) that belong together.

The best way to learn is to practice. Try creating a Car class with make, model, and year attributes, plus start() and drive() methods. Or a Book class with title, author, and pages attributes, plus a read() method.

The more you write classes, the less weird they feel.

Final Words + More Resources

My intention with this article was to help others share my knowledge and experience. If you want to contact me, you can contact by email: Email me

Here are also the most important links from this article along with some further resources that will help you in this scope:

Oh, and if you found these resources useful, don’t forget to support me by starring the repo on GitHub!

Comments