Python Classes and Objects

In Python, writing code is easy, but organizing it well is what makes your programs truly powerful. As projects grow, you don’t just deal with functions and variables anymore; you start working with real-world things such as users, files, products that have both data and behavior.

This is where classes come in. A class lets you bundle related data and functionality into a single structure, making your code cleaner, reusable, and easier to scale. Instead of managing scattered variables and functions, you model your program around real-world concepts.

In this guide, you learn what Python classes are, how they work, and how to uses them effectively with practical example.

What Is a Class in Python?

A class is a blueprint for creating objects. It defines:

  • Attributes: data (what the object has)
  • Methods: behavior (what the object can do)

What Is an Object in Python?

An object (instance) is a specific item created from that blueprint. A class is the template, and an object is the real thing created from it.

In simple terms:

  • Class → Template
  • Object → Actual item created from the template

Defining a Class

You can define a class in Python using a class keyword.

For example:

class Dog:
    # A class attribute, shared by all instances
    species = "Canine"
    
    # The __init__ method (constructor) initializes a new instance
    def __init__(self, name, age):
        self.name = name # Instance attribute, unique to each instance
        self.age = age   # instance attribute, unique to each instance

    # A method (instance function)
    def bark(self):
        return f"{self.name} says woof!"

In this code example, we define a class called Dog, which serves as a blueprint for creating dog objects. The class has a class attribute called species, which is shared by all instances of the Dog class and is set to "Canine".

The class also includes an __init__ method, known as the constructor, which is automatically called when a new Dog object is created. This method initializes instance attributes, name and age, which are unique to each individual dog.

Additionally, the Dog class defines an instance method called bark, which represents a behavior of a dog. It uses the object’s name attribute to return a message showing that the dog is barking.

Note: An object and an instance usually mean the same thing in practice.

Creating and Using Objects

# Create two instances (objects) of the Dog class
d1 = Dog("Tommy", 2)
d2 = Dog("Bud", 4)

# Access instance attributes
print(f"Dog1 name: {d1.name}")
print(f"Dog2 name: {d2.name}")

# Access class attribute (Recommended way)
print(f"Species (via class): {Dog.species}")

# Access class attribute (via instance)
print(f"Dog1 species: {d1.species}")
print(f"Dog2 species: {d2.species}")

# Call methods
print(d1.bark())
print(d2.bark())

Output:

Dog1 name: Tommy
Dog2 name: Bud
Species (via class): Canine
Dog1 species: Canine
Dog2 species: Canine
Tommy says woof!
Bud says woof!

In this code example, we create two instances of Dog class named d1 and d2. The constructor (__init__) is called for each object, assigning "Tommy" and 2 to d1, and "Bud" and 4 to d2 as their respective name and age instance attributes.

Next, we access the instance attribute name using each object. Since instance attributes are unique to each object, d1.name and d2.name return different values corresponding to each dog. Similarly, you can access age attribute too.

You can access the class attribute species using the class itself (Dog.species), which indicates that species belongs to the class and is shared by all instances of Dog class. The species class attribute can also be accessed through each instance (d1.species and d2.species), which shows that all objects share the same class-level data.

Finally, the bark method is called on both d1 and d2. Each method call uses the object’s own name attribute, resulting in different output message for each dog, even though the same method definition is used.