Skip to content
beginner

OOP Basics in Python: Classes and Objects

You have written scripts that run top to bottom. You have grouped steps into functions so you can call them again. Then your program grows, and something…

Published 2026-09-05Updated 2026-09-129 min read
From above of surface of wavy blue sea on sunny day as background
From above of surface of wavy blue sea on sunny day as background. Photo by Francesco Ungaro on Pexels.

You have written scripts that run top to bottom. You have grouped steps into functions so you can call them again. Then your program grows, and something starts to feel off. The data about one thing—say, a customer or a task—is scattered across several variables, and the functions that work on that data live somewhere else entirely.

Object-oriented programming is one response to that scattered feeling. It is a way to bundle related data and behavior together so your code reads like a collection of things that can act, instead of a long list of steps. But here is the part most tutorials skip: classes are a tool, not a requirement. The real question is whether your data and the actions on that data naturally travel together.

What Is Object-Oriented Programming?

Object-oriented programming—OOP for short—is a way to organize code by grouping related data and behavior into objects. An object is simply a bundle that holds both information and the actions that can be performed with that information.

Think about the difference from what you already know. When you write procedural code, you create variables to hold data and functions to act on that data. The two live separately. You might have a dictionary called user and a function called send_email(user). The connection between them exists only in your head.

With OOP, the data and the actions travel together. A User object holds the user's name and email address, and it also knows how to send itself an email. The relationship is built into the code.

Here is the part that surprises most beginners: OOP does not change what your program does. A program written with classes can produce exactly the same output as one written with functions and variables. What changes is how the code is organized, how easy it is to read, and how easy it is to extend later.

Python does not force you to use OOP. You can write perfectly good programs with plain functions for a long time. But Python supports classes fully, and many of the libraries you will use on the job are built around them. Learning the basics of Python OOP means you can both write your own classes and understand code that other people have written.

Knowledge check

Check your understanding

Answer this question before you continue.

What is the main organizational idea of object-oriented programming described in the article?
Single Choice

Focus: Identify what object-oriented programming groups together.

Classes Are Blueprints, Objects Are the Real Things

A central Dog class blueprint connects to two separate object cards labeled buddy and luna. Each object shows its own name value, Buddy or Luna, while both share the class-defined structure and behavior.
A class describes the structure and behavior; each object is a separate instance with its own data.

The single most important idea in Python OOP is the difference between a class and an object.

A class is a blueprint. It describes what a thing looks like and what it can do, but it is not the thing itself. An object is a specific instance built from that blueprint, with its own actual data.

A recipe is a class. The cookies you bake from it are objects. Every cookie follows the same recipe, but each one is a separate, real cookie.

Here is what that looks like in Python:

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

buddy = Dog("Buddy")
luna = Dog("Luna")

print(buddy.name)
print(luna.name)
Buddy
Luna

The Dog class defines what every dog object will have: a name. Then we create two separate dog objects, each with its own name. buddy and luna are independent. Changing one does not affect the other.

This is the mental model to hold onto: the class is the template, and each object you create from it is a real, separate instance with its own data.

Knowledge check

Check your understanding

Answer this question before you continue.

In the Dog example, what are `buddy` and `luna`?
Single Choice

Focus: Distinguish a class blueprint from an object instance with its own data.

`class Dog: ...` followed by `buddy = Dog("Buddy")` and `luna = Dog("Luna")`

Attributes: Data That Belongs to an Object

Objects store their own data in attributes. An attribute is just a variable that belongs to a specific object.

In the Dog example, name is an attribute. Each dog object has its own name value.

But where does that attribute get set? Look at the __init__ method in the example. This method runs automatically whenever you create a new object. Its job is to give the new object its starting values.

The self parameter confuses nearly every beginner, so let us settle it now. self refers to the specific object being created or used. When you write self.name = name, you are saying: "On this particular object, store the name that was passed in."

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

buddy = Dog("Buddy", 3)
luna = Dog("Luna", 5)

print(f"{buddy.name} is {buddy.age} years old")
print(f"{luna.name} is {luna.age} years old")
Buddy is 3 years old
Luna is 5 years old

Each object keeps its own data. buddy.age is 3, and luna.age is 5. They were built from the same class, but they do not share their attribute values.

Methods: Actions an Object Can Perform

Objects can also carry behavior. A function that belongs to a class is called a method. Methods are just functions you already know how to write—the only difference is that they are defined inside a class and they act on the object's own data.

You call a method on an object using dot notation: object.method().

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

buddy = Dog("Buddy", 3)
buddy.bark()
print(f"Buddy is {buddy.age}")
buddy.birthday()
print(f"After birthday, Buddy is {buddy.age}")
Buddy says Woof!
Buddy is 3
After birthday, Buddy is 4

Notice what birthday() does. It changes the object's own data. The method reads self.age, adds 1, and stores the new value back. That is the power of bundling data and behavior together: the method knows exactly where to find the data it needs.

Knowledge check

Check your understanding

Answer this question before you continue.

What does the final `print` statement output?
Output Prediction

Focus: Predict how a method changes an object's attribute.

```python
buddy = Dog("Buddy", 3)
buddy.birthday()
print(f"After birthday, Buddy is {buddy.age}")
```

Why Bother? Where OOP Shows Up in Real Code

You might be thinking: "I can do all of this with dictionaries and functions." You can. For small programs, that is often the right call.

But classes start to earn their keep when you work with real libraries and frameworks. Many of the tools you will use in a programming job are built around Python classes and objects.

Think about a data-cleaning script that processes rows from a spreadsheet. Without classes, you might write a function that takes a row dictionary and returns a cleaned dictionary. The data and the cleaning logic are separate. With a class, each row becomes an object with attributes for the column values and methods for cleaning or validating that row:

class SalesRow:
    def __init__(self, date, amount):
        self.date = date
        self.amount = amount

    def cleaned_amount(self):
        return float(self.amount.replace("$", ""))

The same pattern shows up everywhere. A web application might model a customer as an object with attributes like name and email and methods like place_order(). An automation script might model a task with a status and a method to mark it complete.

Here is the practical point: even if you never write your own class, you will constantly use objects created from classes written by other people. When a library gives you a request object or a session object, you call methods on it with dot notation. Understanding how classes work means you can read those libraries, use them correctly, and debug them when something goes wrong.

Common Beginner Mistakes

Every beginner hits the same few walls when learning Python classes. Here are the ones to expect.

Forgetting self in a method definition. Every method that acts on an object's data needs self as its first parameter. If you forget it, Python will complain when you call the method.

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

    def greet():  # Missing self!
        print("Woof!")

buddy = Dog("Buddy")
buddy.greet()
TypeError: greet() takes 0 positional arguments but 1 was given

The fix is to add self as the first parameter:

    def greet(self):
        print("Woof!")

Confusing the class with an object. The class is the blueprint. You cannot call an instance method on the class itself. You must first create an object.

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

    def greet(self):
        print(f"{self.name} says Woof!")

# Wrong: calling a method on the class
Dog.greet()

# Right: create an object first
buddy = Dog("Buddy")
buddy.greet()
TypeError: Dog.greet() missing 1 required positional argument: 'self'
Buddy says Woof!

Forgetting the parentheses when creating an object. To create an object, you call the class like a function: Dog("Buddy"). If you write buddy = Dog without parentheses, you have just made another name for the class, not an object.

These mistakes are normal. They are part of learning the shape of the syntax. When you hit one, read the error message, check whether self is present, and confirm you created an object with parentheses.

Knowledge check

Check your understanding

Answer this question before you continue.

Which change fixes the method-definition error in this class?
Debugging

Focus: Correct a method definition so it can be called on an object.

```python
class Dog:
    def greet():
        print("Woof!")

buddy = Dog("Buddy")
buddy.greet()
```

When to Use Classes (and When Not To)

Classes are a tool, not a requirement. Knowing when not to use them is part of learning Python OOP basics.

A good rule of thumb: use a class when you have several pieces of data that always travel together, and actions that always operate on that data. If you keep passing the same group of variables into the same group of functions, a class will probably make the code clearer.

Skip classes for short scripts where a few variables and functions are simpler. If you are writing a 20-line script to rename files or parse a log, a class adds ceremony without adding clarity.

Choosing the simpler option is a sign of judgment, not weakness. I have seen beginners force every small script into classes because they thought that was what professional programmers do. The professionals are the ones who know when a plain function is the better tool.

Your Next Step

Open a Python file and write your own small class. Try a Student class with two attributes—name and grade—and one method called introduce() that prints something like "Hi, I'm Alex and I'm in grade 7." Create two student objects with different data, call the method on each, and confirm each object prints its own information.

Run it. Break it. Fix it. That loop is how the concept becomes yours.

You now know the core of Python OOP: classes are blueprints, objects are the real things built from them, attributes hold each object's data, and methods act on that data. The natural next step is inheritance—creating new classes from existing ones—but that is a topic for another day. For now, build a few small classes, get comfortable with self and __init__, and let the mental model settle.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

Which situation best matches the article's rule of thumb for using a class?
Question 1 of 2Misconception Check

Focus: Decide when a class is likely to make code clearer.

If two `Student` objects are created with different names and grades, what should happen when each object's `introduce()` method is called, assuming the method uses that object's attributes?
Question 2 of 2Single Choice

Focus: Apply the idea that each object stores its own attribute values.

References

  1. 9. Classes — Python 3.14.7 documentationdocs.python.org
8sources checked
8source domains
5searches run

Research updated Sep 5, 2026

Practical resource

Want a more structured Python path?

Use the Python Starter Pack to turn scattered tutorials into a focused practice path.

View the bundle
Coming soon

Python Starter Pack

A compact LearnPyFast PDF pack covering what Python is, installation, your first program, running Python code, and Python versions.

$9
PDF BundleTopic PackPythonBeginner
  • 5 curated chapters
  • Enhanced PDF edition with bundle-only learning guidance
  • Offline-friendly format for focused review
  • Source article links for future online updates

Coming soon

Free Python bundle

Get the LearnPyFast Python Starter Bundle

A focused collection of beginner-friendly Python resources to help you move from setup to building practical projects.

You’ll receive the bundle by email. You can unsubscribe anytime.

No spam. You can unsubscribe anytime. See our Privacy policy.

Related sites

Continue beyond Python

Explore related Worldmonger sites when you want to move from Python basics into JavaScript or LLM application building.

JavaScript tutorialstutorial

LearnJSFast

Beginner-friendly JavaScript tutorials for practical web development and self-taught developers.

JavaScriptFrontendWeb development
Visit LearnJSFast
LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast

Keep learning

Related tutorials

Continue with nearby Python topics and beginner-friendly explanations.