Python Object-Oriented Programming Fundamentals: Classes, Objects, and Methods for Beginners

Master Python OOP basics with hands-on examples. Learn to create classes, objects, instance variables, and methods. Build a complete Car class from scratch with step-by-step explanations and practical exercises.

11 min read

Object-Oriented Programming (OOP) is one of the most powerful programming paradigms, and Python makes it accessible and intuitive. Instead of writing functions that operate on data, OOP allows you to create "objects" that contain both data and the functions that work with that data.

πŸ’‘

🎯 What You'll Learn: In this comprehensive tutorial, you'll discover:

  • What classes and objects are and why they matter
  • How to create your first Python class with the __init__ constructor
  • Understanding instance variables and methods
  • Step-by-step class creation with real terminal examples
  • How to create multiple objects from the same class
  • Accessing and using object attributes and methods
  • Common beginner mistakes and how to avoid them

πŸ€” What is Object-Oriented Programming?

Object-Oriented Programming is like creating blueprints for things in the real world. Think of a car manufacturer - they have a blueprint (class) that defines what every car should have: wheels, engine, brand, model. From this blueprint, they can create many actual cars (objects), each with specific details.

Prerequisites

Before we begin, make sure you have:

  • Python 3 installed on your system
  • Basic understanding of Python variables and functions
  • A terminal or command prompt to run Python scripts
  • A text editor (nano, vim, or any code editor)

πŸš€ Setting Up Our First OOP Project

Let's start by creating our first Python file to explore OOP concepts. We'll follow the same process shown in the terminal session:

touch oop1.py

This command creates a new empty Python file called oop1.py. Now let's examine what we'll build step by step.

πŸ—οΈ Creating Your First Class

A class is like a blueprint or template for creating objects. Let's start with the most basic class structure:

nano oop1.py

Let's begin with a simple Car class:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

Let's view what we've created:

cat oop1.py

Output:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

πŸ” Understanding Class Components

Let's break down each part of our class:

ComponentSyntaxPurpose
classclass Car:Defines a new class named Car
initdef init(self, brand, model):Constructor method - runs when object is created
selfselfRefers to the current instance of the class
Instance Variablesself.brand = brandStores data specific to each object
βœ…

βœ… The __init__ Method: This special method is called a constructor. It automatically runs every time you create a new object from the class. The double underscores make it a "magic method" in Python.

πŸ› οΈ Adding Methods to Our Class

A class without methods is like a car without an engine - it has parts but can't do anything. Let's add a method:

nano oop1.py

Now our file contains:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def drive(self):
        print(f"The {self.brand} {self.model} is now driving.")

Let's view the updated file:

cat oop1.py

Output:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def drive(self):
        print(f"The {self.brand} {self.model} is now driving.")

πŸš— Creating Objects (Instances) from Our Class

Now that we have a complete class, let's create actual car objects. Think of this as using our blueprint to build real cars:

nano oop1.py

Our complete file now looks like:

class Car:
    def __init__(self, brand, model):
        self.brand = brand
        self.model = model

    def drive(self):
        print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

Let's view the file:

cat oop1.py

Output:

class Car:
	def __init__(self, brand, model):
        	self.brand = brand
        	self.model = model

	def drive(self):
        	print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

Let's test our code:

python oop1.py

Output:

Wait, nothing happened! That's because we created the objects but didn't tell them to do anything yet.

🎯 Using Object Methods

Let's make our cars actually do something by calling their methods:

nano oop1.py

Our file now includes method calls:

class Car:
	def __init__(self, brand, model):
        	self.brand = brand
        	self.model = model

	def drive(self):
        	print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

car1.drive()
car2.drive()

Let's view the updated file:

cat oop1.py

Output:

class Car:
	def __init__(self, brand, model):
        	self.brand = brand
        	self.model = model

	def drive(self):
        	print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

car1.drive()
car2.drive()

Now let's run it:

python oop1.py

Output:

The Toyota Corolla is now driving.
The Honda Civic is now driving.
βœ…

πŸŽ‰ Success! Our objects are working! Each car object has its own brand and model, and when we call the drive() method, it uses the specific data for that object.

πŸ“Š Accessing Object Attributes

Objects store data in attributes (instance variables). Let's see how to access them directly:

nano oop1.py

Let's add some code to access the attributes:

class Car:
	def __init__(self, brand, model):
        	self.brand = brand
        	self.model = model

	def drive(self):
        	print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

car1.drive()
car2.drive()

print(f"Car 1 brand: {car1.brand}")
print(f"Car 2 brand: {car2.brand}")

Let's view the file:

cat oop1.py

Output:

class Car:
	def __init__(self, brand, model):
        	self.brand = brand
        	self.model = model

	def drive(self):
        	print(f"The {self.brand} {self.model} is now driving.")

car1 = Car("Toyota", "Corolla")
car2 = Car("Honda", "Civic")

car1.drive()
car2.drive()

print(f"Car 1 brand: {car1.brand}")
print(f"Car 2 brand: {car2.brand}")

Let's run the complete script:

python oop1.py

Output:

The Toyota Corolla is now driving.
The Honda Civic is now driving.
Car 1 brand: Toyota
Car 2 brand: Honda

πŸ” Understanding the Object Creation Process

Let's trace through what happens when we create an object:

StepCodeWhat Happens
1car1 = Car("Toyota", "Corolla")Python creates a new Car object
2init(self, "Toyota", "Corolla")The constructor method is automatically called
3self.brand = "Toyota"Brand attribute is set for this specific object
4self.model = "Corolla"Model attribute is set for this specific object
5car1 variableNow points to the completed Car object

πŸ§ͺ Practical Exercise: Adding More Features

Let's extend our Car class with more realistic features:

class Car:
    def __init__(self, brand, model, year, color="White"):
        self.brand = brand
        self.model = model
        self.year = year
        self.color = color
        self.is_running = False
        self.speed = 0

    def start_engine(self):
        if not self.is_running:
            self.is_running = True
            print(f"The {self.brand} {self.model} engine is now running.")
        else:
            print(f"The {self.brand} {self.model} is already running.")

    def stop_engine(self):
        if self.is_running:
            self.is_running = False
            self.speed = 0
            print(f"The {self.brand} {self.model} engine has been turned off.")
        else:
            print(f"The {self.brand} {self.model} is already off.")

    def accelerate(self, speed_increase):
        if self.is_running:
            self.speed += speed_increase
            print(f"The {self.brand} {self.model} is now going {self.speed} km/h.")
        else:
            print("Start the engine first!")

    def describe_car(self):
        status = "running" if self.is_running else "parked"
        print(f"{self.year} {self.color} {self.brand} {self.model} - Currently {status}")
        if self.is_running:
            print(f"Current speed: {self.speed} km/h")

# Create and test our enhanced car
my_car = Car("Tesla", "Model 3", 2023, "Red")
my_car.describe_car()
my_car.start_engine()
my_car.accelerate(50)
my_car.accelerate(30)
my_car.describe_car()
my_car.stop_engine()

🚨 Common Beginner Mistakes

1. Forgetting self in Method Definitions

class Car:
    def drive():  # Missing self parameter
        print("Driving...")
class Car:
    def drive(self):  # Correct with self
        print("Driving...")

2. Accessing Attributes Without self

class Car:
    def __init__(self, brand):
        self.brand = brand

    def show_brand(self):
        print(brand)  # Wrong - should be self.brand
class Car:
    def __init__(self, brand):
        self.brand = brand

    def show_brand(self):
        print(self.brand)  # Correct

3. Forgetting to Call the Constructor

my_car = Car  # This assigns the class, not an instance
my_car = Car("Toyota", "Camry")  # This creates an instance

🎯 Key Concepts Summary

ConceptDefinitionExample
ClassBlueprint for creating objectsclass Car:
ObjectInstance of a classcar1 = Car("Toyota", "Camry")
ConstructorSpecial method that initializes objectsinit(self, brand, model)
Instance VariableData specific to each objectself.brand = brand
MethodFunction that belongs to a classdef drive(self):

🎯 Key Takeaways

βœ… Remember These Points

  1. Classes are blueprints: They define what objects should have and do
  2. Objects are instances: Each object created from a class has its own data
  3. __init__ is the constructor: It runs automatically when objects are created
  4. self refers to the object: Always use self to access object attributes and methods
  5. Methods are functions: They belong to the class and work with object data

πŸš€ What's Next?

In the next part of this series, you'll learn about:

  • Class Variables vs Instance Variables: Understanding the difference and when to use each
  • Inheritance: Creating specialized classes that build on existing ones
  • Method Overriding: Customizing inherited methods for specific needs
  • The super() Function: Calling parent class methods from child classes
βœ…

πŸŽ‰ Congratulations! You've mastered the fundamentals of Python OOP. You can now create classes, instantiate objects, and define methods. These concepts form the foundation for more advanced OOP features.

πŸ’¬ Practice Challenge

Before moving to the next tutorial, try creating your own class:

  1. Create a Book class with attributes for title, author, and pages
  2. Add methods for read(), bookmark(page_number), and get_info()
  3. Create multiple book objects and test all the methods
  4. Add a method to track reading progress
Owais

Written by Owais

I'm an AIOps Engineer with a passion for AI, Operating Systems, Cloud, and Securityβ€”sharing insights that matter in today's tech world.

I completed the UK's Eduqual Level 6 Diploma in AIOps from Al Nafi International College, a globally recognized program that's changing careers worldwide. This diploma is:

  • βœ… Available online in 17+ languages
  • βœ… Includes free student visa guidance for Master's programs in Computer Science fields across the UK, USA, Canada, and more
  • βœ… Comes with job placement support and a 90-day success plan once you land a role
  • βœ… Offers a 1-year internship experience letter while you studyβ€”all with no hidden costs

It's not just a diplomaβ€”it's a career accelerator.

πŸ‘‰ Start your journey today with a 7-day free trial

Related Articles

Continue exploring with these handpicked articles that complement what you just read

More Reading

One more article you might find interesting