- What is a class — the blueprint for creating objects
- What is an object — an instance of a class
- How classes and objects relate — the blueprint vs the building
- Creating objects — instantiating classes
- Multiple objects — creating and managing many objects
- Real-world examples — seeing classes and objects in action
Understanding Classes and Objects
When you start learning Object-Oriented Programming, two terms come up again and again: class and object. These are the most fundamental concepts in OOP, and understanding them is the key to everything else.
Definition: A class is a blueprint or template for creating objects. It defines the structure and behavior that all objects of that type will have. An object is an instance of a class — a specific entity created from the blueprint.
Think of it this way: a class is like the blueprint for a house. It specifies the number of rooms, the layout, and the features. But the blueprint itself is not a house. You can use the blueprint to build many houses, each with its own unique details. The houses are objects.
In Python, everything is an object. Even numbers, strings, and lists are objects. When you create a class, you're defining a new type of object. When you create an instance of that class, you're creating a specific object of that type.
💡 Key concept: A class is a blueprint. An object is the actual thing built from that blueprint. Classes define what objects will look like; objects are the real entities that exist in memory.
The Real-World Analogy
Seeing Classes and Objects in the World Around You
To really understand classes and objects, let's look at some real-world examples. You'll see that this concept is actually very natural — it's how we think about the world.
# Real-World Examples of Classes and Objects
# 1. The "Car" Blueprint
# Class: Car (the blueprint)
# Objects: Your car, my car, a red car, a blue car
# In code:
class Car:
def __init__(self, make, model, color):
self.make = make
self.model = model
self.color = color
self.is_running = False
def start(self):
self.is_running = True
return f"The {self.color} {self.make} {self.model} is now running"
def stop(self):
self.is_running = False
return f"The {self.color} {self.make} {self.model} has stopped"
# Creating objects (actual cars)
my_car = Car("Toyota", "Camry", "Blue")
your_car = Car("Honda", "Civic", "Red")
print(my_car.start()) # The Blue Toyota Camry is now running
print(your_car.start()) # The Red Honda Civic is now running
# 2. The "Person" Blueprint
# Class: Person
# Objects: Alice, Bob, Charlie
class Person:
def __init__(self, name, age, city):
self.name = name
self.age = age
self.city = city
def introduce(self):
return f"Hi, I'm {self.name}, {self.age} years old from {self.city}"
def celebrate_birthday(self):
self.age += 1
return f"Happy birthday! {self.name} is now {self.age}"
# Creating objects
alice = Person("Alice", 25, "NYC")
bob = Person("Bob", 30, "LA")
print(alice.introduce()) # Hi, I'm Alice, 25 years old from NYC
print(bob.introduce()) # Hi, I'm Bob, 30 years old from LA
print(alice.celebrate_birthday()) # Happy birthday! Alice is now 26
# 3. The "Book" Blueprint
# Class: Book
# Objects: Python Guide, Data Science 101, Web Development
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def get_description(self):
return f"'{self.title}' by {self.author}, {self.pages} pages"
# Creating objects
book1 = Book("Python Guide", "John Smith", 350)
book2 = Book("Data Science 101", "Jane Doe", 420)
print(book1.get_description()) # 'Python Guide' by John Smith, 350 pages
print(book2.get_description()) # 'Data Science 101' by Jane Doe, 420 pages
In each example, the class defines the structure (what attributes and methods objects will have), and the objects are the specific instances with their own data. Notice how multiple objects can be created from the same class, each with different values.
Key insight:
- Classes are abstract — they exist as code, not as things
- Objects are concrete — they exist in memory
- One class, many objects — you can create unlimited objects from one class
- Objects have their own data — each object has its own attribute values
Quick Check: What is the relationship between a class and an object? (Answer: A class is a blueprint; an object is an instance of that class)
What is a Class?
Understanding Classes in Detail
A class is a user-defined data type that defines what objects of that type will look like. It's a blueprint that specifies the attributes (data) and methods (behavior) that all objects created from it will have.
Key characteristics of a class:
- It's a template — it defines the structure, not the actual data
- It contains attributes — the data that objects will hold
- It contains methods — the behaviors that objects will have
- It's not an object — it doesn't exist in memory as an entity
- It's reusable — you can create many objects from one class
- It's extensible — you can create subclasses that inherit from it
# Example of a class definition
class Student:
"""A class representing a student"""
# Class attribute (shared by all students)
school = "Python Academy"
# __init__ method (constructor) - called when creating an object
def __init__(self, name, grade, student_id):
# Instance attributes (unique to each student)
self.name = name
self.grade = grade
self.student_id = student_id
self.courses = [] # Empty list for enrolled courses
# Methods (behaviors)
def enroll(self, course):
"""Enroll the student in a course"""
self.courses.append(course)
return f"{self.name} enrolled in {course}"
def get_info(self):
"""Get student information"""
return f"Student: {self.name}, Grade: {self.grade}, ID: {self.student_id}"
def get_courses(self):
"""Get list of enrolled courses"""
return f"{self.name} is taking: {', '.join(self.courses)}"
# The class is just a definition
# No student objects exist yet
# We'll create objects in the next section
In this example, Student is a class. It defines what a student object looks like. Every student will have a name, grade, student_id, and a list of courses. Every student will be able to enroll() in courses and provide get_info(). But the class itself isn't a student — it's just the definition.
Parts of a class:
- Class name — the name of the class (capitalized by convention)
- Class attributes — shared by all objects
- __init__ method — the constructor, initializes objects
- Instance attributes — unique to each object
- Methods — functions that define behavior
- Docstring — documentation for the class
Quick Check: What does a class define? (Answer: The structure and behavior that all objects of that type will have)
What is an Object?
Understanding Objects in Detail
An object is a specific instance of a class. It exists in memory and has its own set of attribute values. When you create an object, you're creating a real entity that follows the blueprint defined by its class.
Key characteristics of an object:
- It's a specific instance — one particular entity of a class
- It has its own data — each object has its own attribute values
- It has behavior — objects can perform methods defined in their class
- It exists in memory — objects are created and stored in memory
- It can be modified — attribute values can change over time
- It's independent — changes to one object don't affect others
# Creating objects from the Student class
# First, let's define the class again
class Student:
"""A class representing a student"""
school = "Python Academy"
def __init__(self, name, grade, student_id):
self.name = name
self.grade = grade
self.student_id = student_id
self.courses = []
def enroll(self, course):
self.courses.append(course)
return f"{self.name} enrolled in {course}"
def get_info(self):
return f"Student: {self.name}, Grade: {self.grade}, ID: {self.student_id}"
def get_courses(self):
return f"{self.name} is taking: {', '.join(self.courses)}"
# Now, let's create student objects
alice = Student("Alice", 10, "S001")
bob = Student("Bob", 9, "S002")
charlie = Student("Charlie", 11, "S003")
# Each object has its own data
print(alice.get_info()) # Student: Alice, Grade: 10, ID: S001
print(bob.get_info()) # Student: Bob, Grade: 9, ID: S002
print(charlie.get_info()) # Student: Charlie, Grade: 11, ID: S003
# Each object can perform the same behaviors with its own data
print(alice.enroll("Math")) # Alice enrolled in Math
print(bob.enroll("Science")) # Bob enrolled in Science
print(charlie.enroll("Math")) # Charlie enrolled in Math
print(alice.get_courses()) # Alice is taking: Math
print(bob.get_courses()) # Bob is taking: Science
print(charlie.get_courses()) # Charlie is taking: Math
# Objects are independent
# Changing one doesn't affect others
alice.grade = 11
print(alice.get_info()) # Student: Alice, Grade: 11, ID: S001
print(bob.get_info()) # Student: Bob, Grade: 9, ID: S002 (unchanged)
Notice that alice, bob, and charlie are all separate objects. They each have their own name, grade, and student_id values. They can all perform the same actions (enroll(), get_info()), but they do so with their own data. This is the essence of OOP — objects are self-contained units that combine data and behavior.
What makes an object:
- State — the data stored in attributes
- Behavior — the methods the object can perform
- Identity — each object has a unique identity
- Encapsulation — data and behavior are combined
Quick Check: What is an object? (Answer: A specific instance of a class that exists in memory)
Creating Objects from Classes
The Process of Instantiation
Creating an object from a class is called instantiation. When you instantiate a class, you're creating a new object in memory. The process is simple: you call the class name like a function, passing any required arguments.
Definition: Instantiation is the process of creating an object from a class. It allocates memory for the object and calls the __init__ method to initialize its attributes.
# Creating objects from various classes
# 1. Creating a simple object
class Dog:
def __init__(self, name, age):
self.name = name
self.age = age
def bark(self):
return f"{self.name} says Woof!"
# Instantiate (create) a Dog object
buddy = Dog("Buddy", 3)
print(buddy.bark()) # Buddy says Woof!
# 2. Creating multiple objects with different data
class Book:
def __init__(self, title, author, pages):
self.title = title
self.author = author
self.pages = pages
def get_info(self):
return f"'{self.title}' by {self.author}"
# Create multiple objects
book1 = Book("Python Guide", "John Smith", 350)
book2 = Book("Data Science", "Jane Doe", 420)
book3 = Book("Web Development", "Bob Johnson", 280)
print(book1.get_info()) # 'Python Guide' by John Smith
print(book2.get_info()) # 'Data Science' by Jane Doe
print(book3.get_info()) # 'Web Development' by Bob Johnson
# 3. Creating objects with default values
class Car:
def __init__(self, make="Toyota", model="Camry", year=2020):
self.make = make
self.model = model
self.year = year
def get_info(self):
return f"{self.year} {self.make} {self.model}"
car1 = Car() # Uses defaults
car2 = Car("Honda", "Civic") # Uses some defaults
car3 = Car("Tesla", "Model 3", 2023) # Custom values
print(car1.get_info()) # 2020 Toyota Camry
print(car2.get_info()) # 2020 Honda Civic
print(car3.get_info()) # 2023 Tesla Model 3
When you create an object, Python does several things behind the scenes:
- Allocates memory — reserves space for the new object
- Calls __init__ — runs the constructor to set up attributes
- Returns the object — gives you a reference to the new object
- Sets self — the self parameter refers to the new object
Creating objects key points:
- Class name as function — call the class like a function
- Pass arguments — these go to the __init__ method
- Assign to variable — store the object reference
- Default values — use default parameters in __init__
- Multiple objects — create as many as you need
Quick Check: What is the process of creating an object called? (Answer: Instantiation)
Attributes and Methods in Action
Using What Objects Know and Do
Once you have an object, you can work with its attributes and methods. Attributes store the object's data, and methods let you perform actions with that data.
# Working with attributes and methods
class Employee:
"""A class representing an employee"""
# Class attribute (shared)
company = "Tech Corp"
def __init__(self, name, position, salary):
# Instance attributes (unique)
self.name = name
self.position = position
self.salary = salary
self.years_at_company = 0
self.performance_rating = 3 # 1-5, default 3
# Methods
def work(self):
return f"{self.name} is working hard!"
def get_raise(self, amount):
self.salary += amount
return f"{self.name} got a raise of ${amount}. New salary: ${self.salary}"
def promote(self, new_position):
self.position = new_position
return f"{self.name} has been promoted to {new_position}"
def add_year(self):
self.years_at_company += 1
return f"{self.name} has been with {self.company} for {self.years_at_company} years"
def set_rating(self, rating):
if 1 <= rating <= 5:
self.performance_rating = rating
return f"{self.name}'s performance rating is now {rating}"
else:
return "Rating must be between 1 and 5"
def get_info(self):
return f"{self.name} - {self.position}, ${self.salary}, Rating: {self.performance_rating}"
# Creating an employee object
alice = Employee("Alice", "Developer", 75000)
# Accessing attributes
print(f"Name: {alice.name}") # Alice
print(f"Position: {alice.position}") # Developer
print(f"Salary: ${alice.salary}") # $75000
print(f"Company: {alice.company}") # Tech Corp
# Using methods
print(alice.work()) # Alice is working hard!
print(alice.get_raise(5000)) # Alice got a raise of $5000. New salary: $80000
print(alice.add_year()) # Alice has been with Tech Corp for 1 years
print(alice.promote("Senior Developer")) # Alice has been promoted to Senior Developer
print(alice.set_rating(4)) # Alice's performance rating is now 4
# Getting complete info
print(alice.get_info()) # Alice - Senior Developer, $80000, Rating: 4
# Modifying attributes directly
alice.salary = 85000
print(f"Updated salary: ${alice.salary}") # Updated salary: $85000
In this example, you can see how attributes store the state of the object and methods provide behavior. The object's state can change over time — Alice gets a raise, gets promoted, and her rating changes. The methods encapsulate the logic for these changes.
Working with objects:
- Access attributes — use dot notation: object.attribute
- Call methods — use dot notation: object.method()
- Modify attributes — assign new values: object.attribute = value
- Methods can change state — methods often modify attributes
Quick Check: How do you access an object's attributes? (Answer: Using dot notation: object.attribute)
Working with Multiple Objects
Managing Collections of Objects
One of the most powerful aspects of OOP is the ability to create and manage multiple objects of the same class. Each object is independent, with its own data, and can be stored in collections like lists or dictionaries.
# Working with multiple objects
class Product:
"""A class representing a product"""
def __init__(self, name, price, category):
self.name = name
self.price = price
self.category = category
self.in_stock = True
def get_info(self):
status = "In Stock" if self.in_stock else "Out of Stock"
return f"{self.name} (${self.price}) - {self.category} - {status}"
def update_price(self, new_price):
if new_price > 0:
self.price = new_price
return f"{self.name} price updated to ${new_price}"
else:
return "Invalid price"
def toggle_stock(self):
self.in_stock = not self.in_stock
status = "in stock" if self.in_stock else "out of stock"
return f"{self.name} is now {status}"
# 1. Creating multiple objects
products = [
Product("Laptop", 999.99, "Electronics"),
Product("Shirt", 29.99, "Clothing"),
Product("Book", 19.99, "Books"),
Product("Phone", 599.99, "Electronics"),
Product("Shoes", 79.99, "Footwear")
]
# 2. Working with all objects
print("All Products:")
for product in products:
print(f" {product.get_info()}")
# 3. Finding products by category
def find_by_category(product_list, category):
return [p for p in product_list if p.category == category]
electronics = find_by_category(products, "Electronics")
print("\nElectronics:")
for product in electronics:
print(f" {product.get_info()}")
# 4. Updating multiple objects
print("\nUpdating products:")
for product in products:
if product.category == "Electronics":
print(product.update_price(product.price * 0.9)) # 10% discount
# 5. Managing inventory
print("\nInventory management:")
products[2].toggle_stock() # Book goes out of stock
products[4].toggle_stock() # Shoes go out of stock
for product in products:
print(f" {product.get_info()}")
This example shows how you can create a collection of objects, work with them individually or as a group, and manage their state. Each Product object is independent — changing one doesn't affect the others.
Managing multiple objects:
- Lists of objects — store objects in lists or other collections
- Filtering — select objects based on criteria
- Bulk operations — perform actions on all objects
- Independent state — each object maintains its own state
Quick Check: Can objects of the same class have different attribute values? (Answer: Yes, each object has its own attribute values)
The Object Lifecycle
From Creation to Destruction
Every object has a lifecycle — it is created, it lives (has state and behavior), and eventually it is destroyed. Understanding this lifecycle helps you manage resources and write better code.
# The lifecycle of an object
class Person:
"""A class representing a person"""
# Class variable to track creations
total_people = 0
def __init__(self, name, age):
"""Constructor - called when object is created"""
self.name = name
self.age = age
Person.total_people += 1
print(f"Person '{name}' created! Total people: {Person.total_people}")
def __del__(self):
"""Destructor - called when object is destroyed"""
Person.total_people -= 1
print(f"Person '{self.name}' destroyed! Total people: {Person.total_people}")
def introduce(self):
return f"Hi, I'm {self.name}, {self.age} years old"
# 1. Creation - objects are created
print("Creating objects...")
alice = Person("Alice", 25)
bob = Person("Bob", 30)
charlie = Person("Charlie", 35)
# 2. During their lifetime - objects have state and behavior
print("\nUsing objects:")
print(alice.introduce())
print(bob.introduce())
print(charlie.introduce())
# 3. Objects can be modified
alice.age = 26
print(f"\nAfter modification: {alice.introduce()}")
# 4. Objects in collections
print("\nObjects in a list:")
people = [alice, bob, charlie]
for person in people:
print(f" {person.introduce()}")
# 5. Objects are independent
bob.age = 31 # Changes only Bob
print(f"\nBob's new age: {bob.age}")
print(f"Alice's age: {alice.age}") # Unchanged
# 6. Objects can be deleted
print("\nDeleting Charlie...")
del charlie # This calls the destructor
# 7. When the program ends, all remaining objects are destroyed
print("\nProgram ending...")
The object lifecycle has three main phases:
- Creation — the object is instantiated with __init__
- Lifetime — the object exists, its state can change, it can perform methods
- Destruction — the object is garbage collected, __del__ is called
Object lifecycle key points:
- Created with class — objects are created by calling the class
- State can change — attributes can be modified during lifetime
- Garbage collected — Python automatically destroys objects when no longer needed
- __del__ method — called when object is destroyed (optional)
Quick Check: What happens when an object is no longer needed? (Answer: It is garbage collected and destroyed)
Try It Yourself
Experiment with classes and objects in the editor below. Create your own classes and objects.
CLASSES AND OBJECTS PRACTICE
========================================
1. DEFINING A CLASS
2. CREATING OBJECTS
3. USING OBJECTS
Buddy the Dog says Woof!
Whiskers the Cat says Meow!
Tweety the Bird says Chirp!
4. MODIFYING OBJECTS
Buddy has been fed!
Buddy is a Dog - Status: Fed
Whiskers is a Cat - Status: Hungry
5. MULTIPLE OBJECTS IN LIST
Buddy is a Dog - Status: Fed
Whiskers is a Cat - Status: Hungry
Tweety is a Bird - Status: Hungry
Classes and objects practice complete!
You've Got It!
You now understand the fundamental concepts of classes and objects in Python. You know the difference between a class (the blueprint) and an object (the actual thing), and how to work with them.
Quick Quiz
Test what you've learned:
Frequently Asked Questions
What is the difference between a class and an object?
Can I create multiple objects from one class?
What is the purpose of the self parameter?
self parameter refers to the current instance of the class. It's used to access attributes and methods of the object. When you call a method on an object, Python automatically passes the object as the first argument (self). This allows methods to access and modify the object's data.
What's a common interview question about classes and objects?
Are classes themselves objects in Python?
type class. This is part of Python's "everything is an object" philosophy. This allows for powerful metaprogramming features.
How do I know if something is a class or an object?
class keyword and is a blueprint. An object is created by calling a class (like a function). You can also use the type() function to check: type(MyClass) returns type(my_object) returns the class it was created from.
Where to Go From Here
Now that you understand classes and objects, check out these related topics:
Creating Class and Object
Learn more about creating classes and objects with detailed examples.
Learn More →OOP vs Procedural Programming
Understand the differences between OOP and procedural programming.
Learn More →Difference Between Classes and Objects
Deep dive into the differences between classes and objects.
Learn More →