Python

Python Objects and Classes Guide | OOP Fundamentals

Master object-oriented programming in Python with practical examples and best practices for efficient development

By InventiveHQ Team

Today we will discuss what objects are, how objects relate to classes, and when you should use objects and classes in your Python applications. This guide provides practical examples to help you master these essential programming concepts.

In Python, a class is a blueprint and an object is a thing built from that blueprint. You define a class once with the class keyword to describe what data an entity holds (its attributes) and what it can do (its methods). You then create as many objects (also called instances) from that class as you need, each with its own independent data but sharing the same methods. The __init__ method runs automatically on creation to set up each object's starting attributes, and self inside every method refers to the specific object being acted on.

That's the one-paragraph summary an AI gives you. What it can't show you is the shape of the relationship: how one class fans out into many independent objects, where self actually points, and which of the many "attribute" concepts you should reach for. The animated diagram, the class-vs-object table, and the class-attribute gotcha below make those concrete.

One Class, Many Objects (at a Glance)

The single most important mental model in object-oriented programming is that one class produces many independent objects. The class is written once; each object carries its own copy of the instance attributes.

One Dog class producing three independent Dog objects A single class blueprint on the left connects by arrows to three separate object instances on the right, each holding its own name and hair length while sharing the same methods. CLASS (blueprint) class Dog: def __init__(self, name) self.name = name self.hairlength = 10 def cut_hair(self, n) Dog(...) max = Dog("Max") name = "Max" hairlength = 8 bella = Dog("Bella") name = "Bella" hairlength = 10 rex = Dog("Rex") name = "Rex" hairlength = 3

Notice that all three objects share the same cut_hair method (defined once in the class) but each holds its own hairlength. Cutting Max's hair leaves Bella and Rex untouched. That independence is the whole point.

Class vs. Object: The Distinction That Trips People Up

Beginners constantly blur these two words. Here is the precise difference:

ClassObject (Instance)
What it isA blueprint / templateA concrete thing built from the blueprint
How manyWritten onceCreated as many times as you need
Exampleclass Dog:mydog = Dog("Max")
HoldsMethod definitions + class attributesIts own instance attribute values
LivesIn your source codeIn memory at runtime
AnalogyThe architectural drawingAn actual house built from the drawing
When you use itDefine the shape and behavior onceEvery time you need a new, independent entity

If you can answer "am I describing the shape, or am I making one of the things?" you can always tell which you need.

What are Objects?

Objects are containers that hold a collection of attributes and functions. Think of objects as real-world entities that have properties (attributes) and can perform actions (methods). For example, you might create an application that tracks dogs.

Object Attributes (Properties)

For each dog you are tracking, you might create an object. Each dog object would have a collection of attributes like:

  • Color: The dog's fur color
  • Age: How old the dog is
  • Breed: What type of dog it is

Object Methods (Actions)

Each dog object also has actions associated with it. For example, you might:

  • Take the dog for a walk
  • Cut the dog's hair
  • Give the dog a bath

Working with Objects – Example

Let's assume you have imported a library that gives you access to an object called Dog. Here's how you would work with it:

# Create a new dog object named Max
mydog = Dog("Max")

# Set Max's breed to Chihuahua
mydog.breed = "Chihuahua"

# Shorten Max's hair length
mydog.cut_hair(2)

# Look at all of the attributes
print(mydog.name)
print(mydog.breed)
print(mydog.hairlength)

What are Classes?

As we discussed in the previous section, an object is a container that holds various attributes and functions. A class is the code that you use to create an object. Think of a class as a blueprint or template for creating objects.

Naming convention: Python's official style guide (PEP 8) recommends CapWords (also called PascalCase) for class names, so Dog, BankAccount, HttpClient. The lowercase dog you may see in older tutorials works, but it makes classes harder to tell apart from variables and functions. We use Dog throughout.

Creating a Basic Class

To create a new class, we use the keyword class. Let's create a new class called Dog with two attributes: breed and name:

class Dog:
    name = ""
    breed = ""

# Create a new instance of this class
mydog = Dog()

# Set the name and breed
mydog.name = "Max"
mydog.breed = "Chihuahua"

# Print the dog's name
print(mydog.name)

Adding an Initialization Function

We probably want to treat the name of the dog as a unique attribute for each of our dogs and ensure that all dogs have names. To do this, we need to add an __init__ function that will be called every time we create a new dog object:

class Dog:
    def __init__(self, name):
        self.name = name
        self.breed = ""

# Create a new dog object named Max
mydog = Dog("Max")

print(mydog.name)  # Output: Max

Key Concept: The self.name assignment tells Python to store the name we passed in on this specific object. self always refers to the particular instance the method is running on, which is how Dog("Max") and Dog("Bella") end up with different names even though they share one class.

Advertisement

What Actually Happens When You Write Dog("Max")

Understanding the order of events removes most of the confusion around __init__ and self. Here is the sequence:

The four steps Python runs when you create an object Left to right: call the class, Python allocates a new empty object, __init__ runs with self bound to that object, and the finished object is returned to your variable. 1. CALL Dog("Max") you call the class 2. ALLOCATE empty object created in memory 3. __init__ self.name = "Max" self = new object 4. RETURN mydog bound to variable

You never call __init__ yourself and you never pass self yourself. Python wires both up for you the moment you call the class.

Adding Methods to Classes

There are various things we will do with our dog. Perhaps we need to cut our dog's hair on occasion. Let's add a new variable called hairlength and a function called cut_hair:

class Dog:
    breed = ""

    # Add hairlength variable to the init function
    def __init__(self, name):
        self.name = name
        self.hairlength = 10

    # Declare the hair-cutting method
    def cut_hair(self, howmuch):
        self.hairlength = self.hairlength - howmuch

# Create a new Dog object named Max
mydog = Dog("Max")

# Call the method to cut the dog's hair
mydog.cut_hair(2)

# Print how long the hair length is now
print(mydog.hairlength)  # Output: 8

As you can see above, we start by creating a new dog object, then we call the cut_hair method. The default value set in __init__ is a hairlength of 10. After cutting 2, the output from the print statement is 8.

The Class-Attribute Gotcha

Notice breed = "" sits directly in the class body, while self.name and self.hairlength are set inside __init__. That difference matters more than it looks:

Instance attributeClass attribute
Where definedself.x = ... inside a methodx = ... in the class body
Shared?Unique to each objectShared by all instances
Good forPer-object state (name, hair length)Shared constants (species, wheel count)
Common bugA mutable default like tricks = [] is shared, so appending on one dog appends to all

The safe rule: keep per-object data as instance attributes set in __init__, and reserve class attributes for values that genuinely should be the same for every instance. If you have ever been baffled by "why did adding a trick to one dog add it to all of them," a mutable class attribute is almost always the cause. This is closely related to how mutable vs. immutable objects behave in Python generally.

When Should You Use Objects and Classes?

Objects and classes allow you to break up your application into smaller, manageable pieces. These smaller pieces can be independently modified and tested. If you have done things right, you can modify one class without worrying about breaking another class.

But classes are not always the right tool. Python is deliberately multi-paradigm, and forcing a class where a plain function would do just adds ceremony. Use this quick decision guide:

SituationReach forWhy
A short script or one-off transformPlain functionsNo lasting state to model; a class adds noise
Data plus the behavior that operates on it, bound togetherA classEncapsulation keeps related code in one place
Many independent things of the same shapeA classOne blueprint, many instances is exactly the class pattern
Just grouping related constantsA module or dataclassLighter weight than a full behavioral class
Modeling a real-world entity with changing stateA classState (attributes) + actions (methods) map cleanly

Key Benefits of Object-Oriented Programming

  • Modularity: Break complex programs into smaller, manageable pieces
  • Reusability: Create classes once and use them multiple times
  • Maintainability: Easier to modify and debug isolated components
  • Scalability: Better organization for larger teams and bigger projects

Best Practices

As your programs get bigger, and you work on larger teams, organization becomes increasingly important. Generally, the rule is that classes should only do one thing, and do that one thing really well. Think of each class as a mini-program within your main program.

Pro Tip: Single Responsibility Principle

For more advanced concepts, consider learning about the SOLID principles of object-oriented design, which provide guidelines for writing clean, maintainable object-oriented code. The first, the Single Responsibility Principle, is simply the "one class, one job" rule stated formally: a class should have only one reason to change.

Summary

Today we have discussed what objects and classes are in Python. We covered how to use objects, how to create classes, and how the two are inter-related. Understanding these concepts is fundamental to writing effective Python code that can scale as your applications grow.

Key Takeaways

  • Objects are containers that hold attributes and methods
  • Classes are blueprints for creating objects; one class produces many independent objects
  • __init__ runs automatically on creation and sets up each object's starting attributes
  • self refers to the specific object a method is acting on
  • Keep per-object data as instance attributes; reserve class attributes for genuinely shared values
  • Object-oriented programming improves code organization and maintainability, but plain functions are often the better fit for short scripts

Keep Learning

Frequently Asked Questions

What is the difference between a class and an object in Python?

A class is the blueprint; an object (also called an instance) is a concrete thing built from that blueprint. Writing class Dog: defines the template once. Writing mydog = Dog("Max") creates one object from it. You can create thousands of independent objects from a single class, each holding its own attribute values while sharing the same methods.

What does __init__ do in a Python class?

__init__ is the initializer (constructor) method. Python calls it automatically every time you create a new object, right after the object is allocated in memory. Its job is to set up the object's starting attributes, for example self.name = name. It must accept self as its first parameter and it should not return a value.

What is self in Python and why is it required?

self is a reference to the specific object the method is acting on. When you call mydog.cut_hair(2), Python passes mydog in as self behind the scenes, so self.hairlength reads and writes the hair length of that exact dog. Every instance method must list self as its first parameter, though you never pass it explicitly at the call site.

Do I have to use classes in Python?

No. Python is multi-paradigm, so short scripts, data-transformation pipelines, and one-off automation often read more clearly with plain functions and dictionaries. Reach for classes when you have data and the behavior that operates on it that naturally belong together, when you need many independent instances of the same shape, or when you want to model a real-world entity with its own state.

What is the difference between a class attribute and an instance attribute?

An instance attribute is set on self inside __init__ (like self.name = name) and is unique to each object. A class attribute is declared directly in the class body (like species = "Canis familiaris") and is shared by every instance. Class attributes are handy for shared constants, but assigning a mutable default such as a list at class level is a classic bug because every instance ends up sharing the same list.

What is the difference between attributes and methods?

Attributes are the data an object holds (its color, age, breed). Methods are the functions defined inside the class that act on that data (walk, cut hair, give a bath). In short, attributes describe what an object is; methods describe what it can do.

How do you create multiple objects from one class?

Call the class like a function once per object: max = Dog("Max"), bella = Dog("Bella"), rex = Dog("Rex"). Each call runs __init__ and returns a brand-new, independent object. Changing max.hairlength has no effect on bella or rex because each holds its own copy of the instance attributes.

What are the four pillars of object-oriented programming?

Encapsulation (bundling data with the methods that use it), abstraction (hiding internal detail behind a simple interface), inheritance (letting one class reuse and extend another), and polymorphism (letting different classes respond to the same method call in their own way). This guide focuses on encapsulation and abstraction, which are the foundation the other two build on.