In the previous lesson, you learned the basic idea of Object-Oriented Programming and why Python programs can be organized around objects. Now we will move from the concept of OOP to one of its most important practical foundations: classes and objects.
A class provides a structure or blueprint from which objects can be created. Objects are the actual instances that we work with in a Python program. Understanding this relationship is essential before moving to more advanced concepts such as constructors, inheritance, encapsulation, and polymorphism.
A class is a blueprint or template used for creating objects. It defines the structure and behavior that objects created from it can have.
Think about a blueprint for a house. The blueprint describes the structure of the house, but the blueprint itself is not the actual house. Multiple houses can be constructed using the same basic blueprint.
Similarly, a Python class describes what an object can contain and what it can do.
For example, suppose we want to represent students in a school management application. We could create a Student class:
class Student:
pass
Here, Student is a class. The class keyword tells Python that we are defining a class, while pass means that the class currently has no implementation.
An empty class may not appear very useful, but it gives us a basic structure that we can use to create objects.
The general syntax for defining a Python class is:
class ClassName:
# class body
For example:
class Student:
pass
By convention, class names in Python are generally written using PascalCase, where each word starts with a capital letter.
Examples include:
class Student:
pass
class BankAccount:
pass
class Product:
pass
class Employee:
pass
The class body can later contain attributes and methods that describe the object.
Classes become useful when we have multiple entities that share a common structure or behavior.
Imagine a school has hundreds of students.
Every student may have:
Students may also perform similar actions:
Instead of designing a completely different structure for every student, we can define one Student class and use it to create many student objects.
This provides a reusable structure and reduces unnecessary repetition.
An object is an instance of a class.
Once we define a class, we can create objects from it.
class Student:
pass
student1 = Student()
Here:
Student is the class.student1 is the object.Student() creates an instance of the class.The class is the blueprint, while the object is the actual instance created from that blueprint.
We can visualize the relationship as:
Student Class
|
↓
Student()
|
↓
student1
Object
One of the important advantages of a class is that we can create multiple objects from the same class.
class Student:
pass
student1 = Student()
student2 = Student()
student3 = Student()
Here, three different objects have been created from the same Student class.
We can think of them as three individual students:
Student Class
|
├── student1
├── student2
└── student3
The class defines the common structure, while each object represents an individual instance.
Although objects are created from the same class, each object is a separate instance.
For example:
class Student:
pass
student1 = Student()
student2 = Student()
student1 and student2 are not the same object. They are two different instances created from the same class.
This distinction becomes important when objects start storing their own data.
For example:
student1.name = "Rahul"
student2.name = "Priya"
Now the two objects can contain different information even though both were created from the same class.
We can assign attributes to an object using the dot operator.
class Student:
pass
student1 = Student()
student1.name = "Rahul"
student1.age = 21
student1.course = "Data Analytics"
Now the object contains three pieces of information:
name → Rahul
age → 21
course → Data Analytics
We can access the values using the dot operator:
print(student1.name)
print(student1.age)
print(student1.course)
Output:
Rahul
21
Data Analytics
This is one of the simplest ways to understand how objects can store information.
Let’s create two student objects:
class Student:
pass
student1 = Student()
student2 = Student()
student1.name = "Rahul"
student1.course = "Python"
student2.name = "Priya"
student2.course = "Data Analytics"
Now each object contains its own values.
print(student1.name)
print(student1.course)
print(student2.name)
print(student2.course)
Output:
Rahul
Python
Priya
Data Analytics
The class is the same, but the objects contain different data.
This is an important concept:
Same Class
↓
Different Objects
↓
Different Data
| Class | Object |
|---|---|
| Blueprint or template | Instance created from a class |
| Defines common structure | Represents an individual entity |
Example: Student |
Example: student1 |
| Can be used to create many objects | Contains data specific to that instance |
Every object created in Python has its own identity. We can inspect an object’s identity using the built-in id() function.
class Student:
pass
student1 = Student()
student2 = Student()
print(id(student1))
print(id(student2))
The exact numbers will vary each time the program runs, but the two objects will have different identities because they are separate instances.
This demonstrates that:
student1 ≠ student2
even though both objects were created from the same class.
We can also use the is operator to check whether two variables refer to the same object:
print(student1 is student2)
Output:
False
This is because student1 and student2 refer to different objects.
The same concept can be applied to products.
class Product:
pass
product1 = Product()
product2 = Product()
We can assign information to each product:
product1.name = "Laptop"
product1.price = 55000
product2.name = "Smartphone"
product2.price = 25000
Now:
print(product1.name)
print(product1.price)
print(product2.name)
print(product2.price)
Output:
Laptop
55000
Smartphone
25000
Again, one class has been used to create multiple objects containing different data.
A useful way to think about a class is as a common definition shared by related objects.
For example:
Class: Product
Possible data:
name
price
quantity
Objects created from the class might represent:
product1 → Laptop
product2 → Smartphone
product3 → Tablet
All three objects belong to the same general category, but each object can represent a different product.
Classes and objects are useful because real applications often contain many types of entities.
A school management system might have:
Student
Teacher
Course
Classroom
Exam
An e-commerce application might have:
Product
Customer
Order
Payment
ShoppingCart
A banking application might have:
Customer
BankAccount
Transaction
Loan
Payment
Each class can represent a particular type of entity, while individual objects represent specific instances of those entities.
class keyword when defining a class.The next part will build on this foundation by introducing attributes, methods, and the self keyword, allowing our classes to contain both meaningful data and useful behavior.
In the previous part, you learned how to create Python classes and objects. You saw that a class acts as a blueprint and that objects are individual instances created from that class. You also learned that multiple objects can be created from the same class and that each object can contain different data.
Now we will take the next step and make our classes more useful by adding attributes and methods. We will also understand one of the most important concepts in Python OOP: the self keyword.
These concepts are essential because a useful class normally needs both data and behavior. Attributes represent the data, while methods represent the behavior or actions that an object can perform.
An attribute is a piece of data associated with an object or class.
Think about a student. A student may have information such as:
These pieces of information can be represented as attributes.
For example:
class Student:
pass
student1 = Student()
student1.name = "Rahul"
student1.age = 21
student1.course = "Data Analytics"
student1.marks = 85
Here, name, age, course, and marks are attributes associated with student1.
We can access them using the dot operator:
print(student1.name)
print(student1.age)
print(student1.course)
print(student1.marks)
Output:
Rahul
21
Data Analytics
85
Attributes can also be modified after an object has been created.
student1.marks = 90
print(student1.marks)
Output:
90
This means the object’s data can change during the execution of the program.
We can also add a new attribute later:
student1.city = "Dehradun"
print(student1.city)
Output:
Dehradun
Although Python allows this flexibility, in well-designed classes it is generally better to define the expected object attributes in a structured way. Later, we will use the __init__() method to do this more cleanly.
One important feature of object-oriented programming is that objects created from the same class can contain different values.
class Student:
pass
student1 = Student()
student2 = Student()
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 85
student2.name = "Priya"
student2.course = "Data Analytics"
student2.marks = 92
Now we can display their information separately:
print(student1.name)
print(student1.course)
print(student1.marks)
print(student2.name)
print(student2.course)
print(student2.marks)
Output:
Rahul
Python
85
Priya
Data Analytics
92
The class is the same, but the objects contain different information.
This can be represented as:
Student Class
|
├── student1
│ ├── name = Rahul
│ ├── course = Python
│ └── marks = 85
|
└── student2
├── name = Priya
├── course = Data Analytics
└── marks = 92
A method is a function defined inside a class.
While attributes represent information, methods represent actions or behavior.
For example, a student may perform actions such as studying, attending a class, or displaying their information.
class Student:
def study(self):
print("Student is studying")
Now create an object:
student1 = Student()
student1.study()
Output:
Student is studying
The study() method defines behavior that can be performed by a Student object.
A class can contain multiple methods.
class Student:
def study(self):
print("Student is studying")
def attend_class(self):
print("Student is attending class")
def submit_assignment(self):
print("Assignment submitted")
We can create an object and call these methods:
student1 = Student()
student1.study()
student1.attend_class()
student1.submit_assignment()
Output:
Student is studying
Student is attending class
Assignment submitted
Now our class represents both information and behavior.
You may have noticed something unusual in the method definitions:
def study(self):
Why do we write self?
In an instance method, self refers to the current object.
This allows the method to access data belonging to that particular object.
For example:
class Student:
def display(self):
print(self.name)
print(self.course)
Now create an object and assign values:
student1 = Student()
student1.name = "Rahul"
student1.course = "Python"
student1.display()
Output:
Rahul
Python
Here:
self.name
means the name attribute belonging to the current object.
Similarly:
self.course
means the course attribute belonging to the current object.
The concept of self becomes much clearer when the same method is used by multiple objects.
class Student:
def display(self):
print("Name:", self.name)
print("Course:", self.course)
student1 = Student()
student1.name = "Rahul"
student1.course = "Python"
student2 = Student()
student2.name = "Priya"
student2.course = "Data Analytics"
student1.display()
student2.display()
Output:
Name: Rahul
Course: Python
Name: Priya
Course: Data Analytics
When this line runs:
student1.display()
self refers to student1.
When this line runs:
student2.display()
self refers to student2.
Therefore, the same method can work with different objects and automatically access the correct object’s data.
You can think of self as saying:
"This particular object"
For example:
self.name
means:
"The name belonging to this particular object."
Similarly:
self.marks
means:
"The marks belonging to this particular object."
This is why self is essential when an instance method needs to work with object-specific data.
Methods can also accept additional parameters.
For example, suppose we want a method that updates a student’s marks:
class Student:
def update_marks(self, new_marks):
self.marks = new_marks
Now:
student1 = Student()
student1.marks = 75
student1.update_marks(88)
print(student1.marks)
Output:
88
Here, self represents the object, while new_marks is an additional value supplied when the method is called.
A method does not always have to print something. It can also calculate and return a value.
class Student:
def calculate_percentage(self, total_marks):
return (self.marks / total_marks) * 100
Now:
student1 = Student()
student1.marks = 450
percentage = student1.calculate_percentage(500)
print(percentage)
Output:
90.0
This is useful because the returned value can be stored in a variable or used in another calculation.
A useful class generally combines data and behavior.
class Student:
def display(self):
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
def calculate_percentage(self, total_marks):
return (self.marks / total_marks) * 100
Now create an object:
student1 = Student()
student1.name = "Rahul"
student1.course = "Data Analytics"
student1.marks = 450
student1.display()
percentage = student1.calculate_percentage(500)
print("Percentage:", percentage)
Output:
Name: Rahul
Course: Data Analytics
Marks: 450
Percentage: 90.0
This is a more realistic example of OOP because the object contains data and the class provides operations that work with that data.
The same principle can be applied to an e-commerce product.
class Product:
def display(self):
print("Product:", self.name)
print("Price:", self.price)
def calculate_total(self, quantity):
return self.price * quantity
Create an object:
product1 = Product()
product1.name = "Laptop"
product1.price = 55000
product1.display()
total = product1.calculate_total(3)
print("Total:", total)
Output:
Product: Laptop
Price: 55000
Total: 165000
The Product object contains information about the product, while its methods provide operations related to that product.
Let’s take another example:
class Employee:
def display(self):
print("Name:", self.name)
print("Department:", self.department)
print("Salary:", self.salary)
def annual_salary(self):
return self.salary * 12
Create an object:
employee1 = Employee()
employee1.name = "Amit"
employee1.department = "Analytics"
employee1.salary = 50000
employee1.display()
print("Annual Salary:", employee1.annual_salary())
Output:
Name: Amit
Department: Analytics
Salary: 50000
Annual Salary: 600000
Again, the class combines data and behavior into one logical structure.
Beginners often make mistakes while using self.
For example, this is incorrect:
class Student:
def display():
print(self.name)
The method is missing the self parameter.
The correct version is:
class Student:
def display(self):
print(self.name)
Another common mistake is forgetting self while accessing an object’s attribute:
class Student:
def display(self):
print(name)
Here, Python will look for a local variable named name. If it does not exist, this can result in an error.
The correct approach is:
class Student:
def display(self):
print(self.name)
At this point, you can think about a class as a combination of data and behavior.
Class
|
├── Attributes
│ ├── name
│ ├── price
│ └── marks
|
└── Methods
├── display()
├── calculate()
└── update()
Objects created from the class contain their own data, while the methods defined by the class provide behavior that works with that data.
self refers to the current object.self.attribute allows a method to access the current object’s data.With classes, objects, attributes, methods, and self now understood, the next step is to learn how to design classes more effectively and how Python initializes object data using the __init__() constructor.
So far, you have learned how to create a class, create objects from that class, store information using attributes, define methods, and use the self keyword to work with the current object. The next step is to combine these concepts into practical classes that solve real programming problems.
A class becomes useful when it represents a meaningful entity and provides operations that work with that entity’s data. Instead of creating unrelated variables and functions throughout a program, we can organize related information and behavior together.
Before creating a class, it is useful to identify three things:
For example, suppose we want to create a student management system.
The entity is:
Student
The student may have data such as:
student_id
name
course
marks
The student may perform actions such as:
display()
calculate_percentage()
is_passed()
This gives us a clear starting point for designing the class.
Let’s create a practical Student class.
class Student:
def display(self):
print("Student ID:", self.student_id)
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
def calculate_percentage(self, total_marks):
return (self.marks / total_marks) * 100
def is_passed(self):
return self.marks >= 40
Now we can create an object and assign its information:
student1 = Student()
student1.student_id = 101
student1.name = "Rahul"
student1.course = "Data Analytics"
student1.marks = 420
We can use the methods defined in the class:
student1.display()
percentage = student1.calculate_percentage(500)
print("Percentage:", percentage)
print("Passed:", student1.is_passed())
Output:
Student ID: 101
Name: Rahul
Course: Data Analytics
Marks: 420
Percentage: 84.0
Passed: True
Notice how the methods operate directly on the object’s data using self.
Methods can accept additional parameters when they need information that is not already stored in the object.
Consider a product class:
class Product:
def calculate_total(self, quantity):
return self.price * quantity
Here, self.price comes from the object, while quantity is provided when the method is called.
For example:
product1 = Product()
product1.name = "Laptop"
product1.price = 55000
total = product1.calculate_total(3)
print(total)
Output:
165000
This distinction is important:
self.price
↓
Data belonging to the object
quantity
↓
Value supplied to the method
Methods can therefore combine information stored inside an object with additional information supplied at the time of the method call.
Methods do not only read data. They can also modify an object’s attributes.
For example, consider a product whose stock quantity needs to be updated.
class Product:
def add_stock(self, quantity):
self.stock += quantity
def remove_stock(self, quantity):
if quantity <= self.stock:
self.stock -= quantity
Create an object:
product1 = Product()
product1.name = "Laptop"
product1.stock = 20
Add stock:
product1.add_stock(10)
print(product1.stock)
Output:
30
Remove stock:
product1.remove_stock(5)
print(product1.stock)
Output:
25
The method changes the state of the object by modifying self.stock.
A method can return a value instead of simply printing something.
This is often preferable when the result needs to be used somewhere else in the program.
class Employee:
def annual_salary(self):
return self.salary * 12
Now:
employee1 = Employee()
employee1.name = "Amit"
employee1.salary = 50000
annual = employee1.annual_salary()
print(annual)
Output:
600000
Because the method returns a value, we can store it in a variable:
annual = employee1.annual_salary()
We could also use the result directly:
print(employee1.annual_salary())
This makes methods flexible and reusable.
Let’s build a more complete example.
class Employee:
def display(self):
print("Employee ID:", self.employee_id)
print("Name:", self.name)
print("Department:", self.department)
print("Monthly Salary:", self.salary)
def annual_salary(self):
return self.salary * 12
def salary_after_raise(self, percentage):
raise_amount = self.salary * percentage / 100
return self.salary + raise_amount
Create an employee:
employee1 = Employee()
employee1.employee_id = 501
employee1.name = "Amit"
employee1.department = "Analytics"
employee1.salary = 50000
Now use the methods:
employee1.display()
print("Annual Salary:", employee1.annual_salary())
print(
"Salary after 10% raise:",
employee1.salary_after_raise(10)
)
Output:
Employee ID: 501
Name: Amit
Department: Analytics
Monthly Salary: 50000
Annual Salary: 600000
Salary after 10% raise: 55000.0
This example demonstrates how multiple methods can operate on the same object’s data.
Bank accounts are another useful example because they contain data and several related operations.
class BankAccount:
def display_balance(self):
print("Balance:", self.balance)
def deposit(self, amount):
if amount > 0:
self.balance += amount
def withdraw(self, amount):
if amount > 0 and amount <= self.balance:
self.balance -= amount
Create an account:
account1 = BankAccount()
account1.account_holder = "Rahul"
account1.balance = 10000
Deposit money:
account1.deposit(5000)
account1.display_balance()
Output:
Balance: 15000
Withdraw money:
account1.withdraw(3000)
account1.display_balance()
Output:
Balance: 12000
The class keeps the operations related to the bank account together.
A major advantage of classes is that one class can be used to create many objects.
For example:
class Employee:
def display(self):
print(self.name, "-", self.department)
def annual_salary(self):
return self.salary * 12
Now create several employees:
employee1 = Employee()
employee1.name = "Amit"
employee1.department = "Analytics"
employee1.salary = 50000
employee2 = Employee()
employee2.name = "Priya"
employee2.department = "Marketing"
employee2.salary = 45000
employee3 = Employee()
employee3.name = "Rohit"
employee3.department = "Sales"
employee3.salary = 40000
We can use the same method for all three:
employee1.display()
employee2.display()
employee3.display()
Output:
Amit - Analytics
Priya - Marketing
Rohit - Sales
One class has provided a common structure and common behavior for all employees.
Objects can also be stored in Python collections such as lists.
employees = [employee1, employee2, employee3]
for employee in employees:
employee.display()
This becomes particularly useful when working with larger datasets or applications containing many objects.
We can also calculate the total salary:
total_salary = 0
for employee in employees:
total_salary += employee.salary
print("Total Monthly Salary:", total_salary)
Output:
Total Monthly Salary: 135000
This demonstrates how objects can work naturally with Python’s existing data structures.
If we simply print an object:
print(employee1)
Python normally displays a representation containing information about the object rather than a meaningful business description.
For example, you may see output similar to:
<__main__.Employee object at 0x...>
This happens because Python does not automatically know how you want your custom object to be displayed.
Later in the OOP course, you can learn about special methods such as __str__() that allow you to define a more meaningful representation of an object.
When designing a class, try to keep its responsibilities clear.
For example, a Student class should primarily deal with information and behavior related to students.
A Product class should deal with product-related information and operations.
A BankAccount class should deal with account-related information and operations.
Avoid putting completely unrelated responsibilities into the same class.
For example, a class named Student should not suddenly contain methods for managing bank transactions and processing product inventory unless there is a strong design reason for doing so.
A useful design principle is:
One Class
↓
One Clear Responsibility
↓
Related Data + Related Behavior
self when accessing object attributes.Before creating a class, ask yourself:
For example, for a Product class:
Entity:
Product
Data:
name
price
stock
Behavior:
display()
calculate_total()
add_stock()
remove_stock()
This simple planning process can make class design much easier.
Classes and objects are not limited to educational examples. They can represent components of real applications.
A Data Analytics application might contain objects representing:
An e-commerce application could contain:
A school management system could contain:
Each entity can potentially become a class when the application requires that level of organization.
At this point, you can create useful classes, create multiple objects, give those objects data, and define methods that work with their data. The next part will complete this lesson with practice, common interview questions, coding exercises, and a practical mini-project that combines the concepts you have learned.
You have now learned how to create classes, create objects, add attributes, define methods, use the self keyword, and design practical classes. The best way to make these concepts permanent is to practice them through complete examples and programming problems.
In real Python development, understanding the syntax of a class is only the beginning. You also need to decide what a class should represent, what data its objects should contain, and what behavior should be implemented through its methods.
Before moving to practical exercises, let’s review the most important concepts from this lesson.
| Concept | Meaning | Example |
|---|---|---|
| Class | A blueprint used to create objects | class Student: |
| Object | An instance of a class | student1 = Student() |
| Attribute | Data associated with an object | student1.name |
| Method | A function defined inside a class | student1.display() |
| self | Reference to the current object | self.name |
A simple mental model is:
Class
↓
Creates
↓
Object
↓
Contains
├── Attributes
└── Uses Methods
↓
self
Let’s create a simple student class.
class Student:
def display(self):
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
def is_passed(self):
return self.marks >= 40
Now create two students:
student1 = Student()
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 85
student2 = Student()
student2.name = "Priya"
student2.course = "Data Analytics"
student2.marks = 32
We can display their information:
student1.display()
print("Passed:", student1.is_passed())
student2.display()
print("Passed:", student2.is_passed())
Output:
Name: Rahul
Course: Python
Marks: 85
Passed: True
Name: Priya
Course: Data Analytics
Marks: 32
Passed: False
Notice that the same methods work for both objects. The value of self changes depending on which object calls the method.
Now consider an e-commerce product.
class Product:
def display(self):
print("Product:", self.name)
print("Price:", self.price)
print("Stock:", self.stock)
def calculate_total(self, quantity):
return self.price * quantity
def add_stock(self, quantity):
self.stock += quantity
Create a product:
product1 = Product()
product1.name = "Laptop"
product1.price = 55000
product1.stock = 20
Display its information:
product1.display()
Calculate the cost of purchasing three laptops:
total = product1.calculate_total(3)
print("Total:", total)
Output:
Total: 165000
We can also update the stock:
product1.add_stock(10)
print("Updated Stock:", product1.stock)
Output:
Updated Stock: 30
This example demonstrates that an object can store information and provide methods that operate on that information.
A bank account is another useful example because it naturally contains both data and behavior.
class BankAccount:
def display_balance(self):
print("Account Holder:", self.account_holder)
print("Balance:", self.balance)
def deposit(self, amount):
if amount > 0:
self.balance += amount
def withdraw(self, amount):
if amount > 0 and amount <= self.balance:
self.balance -= amount
else:
print("Invalid withdrawal")
Create an account:
account1 = BankAccount()
account1.account_holder = "Rahul"
account1.balance = 10000
Display the initial balance:
account1.display_balance()
Deposit money:
account1.deposit(5000)
account1.display_balance()
Withdraw money:
account1.withdraw(3000)
account1.display_balance()
The object maintains its own balance, while the methods control the operations performed on that balance.
Let’s create an employee class.
class Employee:
def display(self):
print("Employee:", self.name)
print("Department:", self.department)
print("Salary:", self.salary)
def annual_salary(self):
return self.salary * 12
def salary_after_raise(self, percentage):
increase = self.salary * percentage / 100
return self.salary + increase
Create an employee:
employee1 = Employee()
employee1.name = "Amit"
employee1.department = "Analytics"
employee1.salary = 50000
Use the methods:
employee1.display()
print("Annual Salary:", employee1.annual_salary())
print(
"Salary after 10% raise:",
employee1.salary_after_raise(10)
)
Output:
Employee: Amit
Department: Analytics
Salary: 50000
Annual Salary: 600000
Salary after 10% raise: 55000.0
One of the biggest advantages of classes is that we can create many objects from the same class.
class Employee:
def display(self):
print(self.name, "-", self.department)
Create several employees:
employee1 = Employee()
employee1.name = "Amit"
employee1.department = "Analytics"
employee2 = Employee()
employee2.name = "Priya"
employee2.department = "Marketing"
employee3 = Employee()
employee3.name = "Rohit"
employee3.department = "Sales"
Store them in a list:
employees = [employee1, employee2, employee3]
Now use a loop:
for employee in employees:
employee.display()
Output:
Amit - Analytics
Priya - Marketing
Rohit - Sales
This pattern becomes very useful when programs need to work with many related objects.
Try solving the following exercises without looking at the solution first.
Car class and create an object containing the car’s brand, model, and price.Book class with attributes for title, author, and price. Create two book objects.Rectangle class with attributes for length and width and a method to calculate area.Circle class with a radius attribute and a method to calculate area.Employee class with a method that calculates annual salary.Student class with a method that determines whether a student has passed.Product class with a method that calculates the total cost based on price and quantity.BankAccount class with deposit and withdrawal methods.Temperature class with a method that converts Celsius to Fahrenheit.ShoppingCart class that stores product prices and calculates the total amount.Suppose the exercise asks you to create a rectangle class that calculates area.
class Rectangle:
def area(self):
return self.length * self.width
Create the object:
rectangle1 = Rectangle()
rectangle1.length = 10
rectangle1.width = 5
print(rectangle1.area())
Output:
50
The object’s attributes provide the data, while the method performs the calculation.
Here are some common beginner-level interview questions related to Python classes and objects.
1. What is a class in Python?
A class is a blueprint or template used to create objects.
2. What is an object?
An object is an instance of a class.
3. Can one class create multiple objects?
Yes. A single class can be used to create many objects.
4. Can objects created from the same class have different values?
Yes. Each object can maintain its own attribute values.
5. What is a method?
A method is a function defined inside a class.
6. What does self represent?
self refers to the current object in an instance method.
7. What is an attribute?
An attribute is data associated with an object or class.
8. What is the difference between a class and an object?
A class is a blueprint, while an object is an instance created from that blueprint.
9. Why are classes useful?
Classes provide a way to organize related data and behavior into reusable structures.
10. Can a method return a value?
Yes. A method can use the return statement to return a value.
Let’s combine the concepts from this lesson into a small project.
The objective is to create a simple student management structure using a Student class.
class Student:
def display(self):
print("ID:", self.student_id)
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
def percentage(self, total_marks):
return (self.marks / total_marks) * 100
def is_passed(self):
return self.marks >= 40
Create three students:
student1 = Student()
student1.student_id = 101
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 420
student2 = Student()
student2.student_id = 102
student2.name = "Priya"
student2.course = "Data Analytics"
student2.marks = 460
student3 = Student()
student3.student_id = 103
student3.name = "Amit"
student3.course = "Python"
student3.marks = 350
Put the objects into a list:
students = [student1, student2, student3]
Now process them:
for student in students:
student.display()
print(
"Percentage:",
student.percentage(500)
)
print(
"Passed:",
student.is_passed()
)
print("--------------------")
This small project demonstrates several important concepts:
selfNow try improving the student management project yourself.
Add the following features:
For example, a grade method could conceptually work like this:
if marks >= 90:
grade = "A+"
elif marks >= 80:
grade = "A"
elif marks >= 70:
grade = "B"
elif marks >= 60:
grade = "C"
else:
grade = "D"
Try implementing this logic inside a class method.
Can a class exist without creating an object?
Yes. A class can be defined without immediately creating an object. The class definition remains available for creating objects later.
Can we create many objects from one class?
Yes. This is one of the major purposes of classes.
Do all objects have the same data?
No. Objects created from the same class can contain different attribute values.
Do all objects have the same methods?
Objects created from the same class normally have access to the methods defined by that class.
Why is self important?
It allows an instance method to access and work with the data belonging to the current object.
Can a method modify an object?
Yes. A method can modify an object’s attributes using self.
Can a method return a result?
Yes. Methods can calculate and return values using return.
In this lesson, you learned how Python classes and objects form the foundation of Object-Oriented Programming.
You learned that a class is a blueprint used to create objects, while an object is an individual instance of that class. You learned how to create classes using the class keyword and create objects by calling the class.
You also learned how objects can contain attributes representing their data and how methods represent behavior. The self keyword allows instance methods to access and modify the data belonging to the current object.
You practiced these concepts using students, products, employees, bank accounts, and other real-world examples. You also learned how multiple objects can be stored in lists and processed using loops.
The most important mental model to remember is:
Class
↓
Blueprint
↓
Creates Objects
↓
Objects contain Data
+
Objects use Methods
↓
self refers to the Current Object
These concepts are the foundation for the next stage of Python OOP.
In the next lesson, we will study Python Constructors and the __init__() Method.
So far, you have been creating an object first and then manually assigning its attributes:
student1 = Student()
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 85
Python provides a much cleaner way to initialize object data when an object is created. This is where the __init__() method becomes important.
In the next lesson, you will learn how constructors can automatically initialize object attributes and make your classes cleaner, more structured, and easier to use.
By this point, you have learned the core ideas behind Python Classes and Objects. You know that a class provides a reusable structure, an object is an instance of that class, attributes represent data, methods represent behavior, and self allows an instance method to work with the current object.
The purpose of this final part is to strengthen those concepts through revision, practical examples, coding exercises, interview questions, and a small project. The goal is not simply to remember Python OOP syntax, but to understand how and when classes and objects should be used.
A class is a blueprint or template used to create objects.
class Student:
pass
An object is created from the class:
student1 = Student()
Here, Student is the class and student1 is the object.
We can create multiple objects from the same class:
student1 = Student()
student2 = Student()
student3 = Student()
Each object is a separate instance and can contain different data.
student1.name = "Rahul"
student2.name = "Priya"
student3.name = "Amit"
The same class has produced three different objects with different attribute values.
An attribute represents information associated with an object.
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 85
A method is a function defined inside a class.
class Student:
def display(self):
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
The object can call the method:
student1.display()
The method can access the object’s data through self.
The self keyword refers to the current object.
Suppose we have:
class Student:
def display(self):
print(self.name)
When we execute:
student1.display()
self refers to student1.
If we execute:
student2.display()
self refers to student2.
Therefore, the same method can work with different objects.
class Student:
def display(self):
print("Student:", self.name)
student1 = Student()
student1.name = "Rahul"
student2 = Student()
student2.name = "Priya"
student1.display()
student2.display()
Output:
Student: Rahul
Student: Priya
This is one of the most important ideas to understand before moving to advanced Python OOP.
| Class | Object |
|---|---|
| Blueprint or template | Instance of a class |
| Defines common structure | Represents a particular entity |
Example: Student |
Example: student1 |
| Used to create objects | Stores object-specific data |
| Can contain methods | Can call those methods |
Not every Python problem requires a class.
If you need to perform a simple calculation, a normal function may be enough:
def calculate_total(price, quantity):
return price * quantity
There is no need to create a class simply because Python supports OOP.
Classes become more useful when your program contains entities that have both data and behavior.
For example, a banking application may have:
BankAccount
↓
balance
account_holder
account_number
Methods:
deposit()
withdraw()
display_balance()
An e-commerce application may have:
Product
↓
name
price
stock
Methods:
display()
calculate_total()
add_stock()
remove_stock()
A school management system may have:
Student
↓
name
course
marks
Methods:
display()
calculate_percentage()
is_passed()
In such situations, classes provide a natural way to organize the application.
Try solving these problems independently.
Car class with attributes brand, model, and price. Create two objects and display their information.Book class with attributes title, author, and price. Add a method to display book details.Rectangle class with length and width attributes. Add a method that calculates the area.Circle class with a radius attribute and a method that calculates its area.Employee class with name and salary attributes. Add a method that calculates annual salary.Student class with name and marks attributes. Add a method that returns whether the student passed.Product class with price and quantity. Add a method to calculate the total purchase amount.BankAccount class with balance, deposit, and withdrawal methods.Temperature class with a Celsius value and a method to convert Celsius to Fahrenheit.ShoppingCart class that can calculate the total price of products.Let’s solve one of the exercises.
class Rectangle:
def area(self):
return self.length * self.width
def perimeter(self):
return 2 * (self.length + self.width)
Create an object:
rectangle1 = Rectangle()
rectangle1.length = 10
rectangle1.width = 5
Now calculate the area and perimeter:
print("Area:", rectangle1.area())
print("Perimeter:", rectangle1.perimeter())
Output:
Area: 50
Perimeter: 30
Notice that both methods use the same object’s attributes through self.
Consider a temperature conversion class:
class Temperature:
def celsius_to_fahrenheit(self):
return (self.celsius * 9 / 5) + 32
Create an object:
temperature1 = Temperature()
temperature1.celsius = 25
print(
temperature1.celsius_to_fahrenheit()
)
Output:
77.0
This is another example of a method performing an operation using data stored inside an object.
1. What is a class in Python?
A class is a blueprint or template used to create objects.
2. What is an object?
An object is an instance of a class.
3. Can one class have multiple objects?
Yes. A single class can be used to create many objects.
4. Can objects created from the same class contain different data?
Yes. Each object can have its own attribute values.
5. What is an attribute?
An attribute is data associated with an object or class.
6. What is a method?
A method is a function defined inside a class.
7. What does self mean in Python?
self refers to the current object inside an instance method.
8. Why do we use self.name?
self.name accesses the name attribute belonging to the current object.
9. Can a method accept parameters?
Yes. Methods can accept additional parameters besides self.
10. Can a method return a value?
Yes. A method can use return to provide a result.
Let’s combine the concepts from this lesson into a small practical project.
The objective is to create a simple system that represents students and provides basic operations on their information.
class Student:
def display(self):
print("Student ID:", self.student_id)
print("Name:", self.name)
print("Course:", self.course)
print("Marks:", self.marks)
def percentage(self, total_marks):
return (self.marks / total_marks) * 100
def is_passed(self):
return self.marks >= 40
def grade(self):
percentage = self.percentage(500)
if percentage >= 90:
return "A+"
elif percentage >= 80:
return "A"
elif percentage >= 70:
return "B"
elif percentage >= 60:
return "C"
elif percentage >= 40:
return "D"
else:
return "F"
Now create some student objects:
student1 = Student()
student1.student_id = 101
student1.name = "Rahul"
student1.course = "Python"
student1.marks = 450
student2 = Student()
student2.student_id = 102
student2.name = "Priya"
student2.course = "Data Analytics"
student2.marks = 380
student3 = Student()
student3.student_id = 103
student3.name = "Amit"
student3.course = "Python"
student3.marks = 320
Store them in a list:
students = [student1, student2, student3]
Now process all students:
for student in students:
student.display()
print("Percentage:", student.percentage(500))
print("Grade:", student.grade())
print("Passed:", student.is_passed())
print("----------------------")
This small project demonstrates several concepts together:
selfNow improve the project yourself.
Add the following features:
Do not worry if you cannot solve the complete challenge immediately. The purpose is to make you think about how classes, attributes, methods, and objects can work together to solve a larger problem.
There are several mistakes beginners commonly make while learning classes and objects.
Mistake 1: Confusing a class with an object
Student
is a class, while:
student1 = Student()
creates an object.
Mistake 2: Forgetting self
Incorrect:
def display():
print(name)
Correct:
def display(self):
print(self.name)
Mistake 3: Forgetting that objects are separate
If you create:
student1 = Student()
student2 = Student()
they are two separate objects. Changing the data of one does not automatically change the other.
Mistake 4: Using classes for every tiny problem
A class is not necessary for every Python program. Sometimes a function or a few variables are simpler and more appropriate.
Mistake 5: Creating overly complicated classes
Start with a clear responsibility. Add complexity only when the application actually requires it.
In this lesson, you learned the practical foundation of Python Classes and Objects.
You learned that a class provides a blueprint for creating objects, while an object represents a specific instance of that class. You learned how to create multiple objects from one class and how each object can maintain its own data.
You also learned about attributes, which represent object data, and methods, which represent behavior. The self keyword allows methods to access and work with the current object’s attributes.
You practiced creating classes for students, products, employees, bank accounts, rectangles, and other real-world entities. You also learned how objects can be stored in lists and processed using loops.
The most important structure to remember is:
Class
↓
Blueprint
↓
Creates Objects
↓
Objects contain Attributes
+
Objects use Methods
↓
self → Current Object
Once this structure becomes comfortable, Python OOP becomes much easier to understand.
self.Before moving forward, try creating your own class without copying an existing example.
Choose one real-world entity such as:
Then identify at least three attributes and three methods.
For example:
Class: OnlineCourse
Attributes:
name
price
duration
Methods:
display()
calculate_discount()
final_price()
Build the class, create at least three objects, and test every method.
If you can complete this exercise independently, you have a strong practical foundation in Python classes and objects.
In the next lesson, we will move to Python Constructors and the __init__() Method. You have so far been assigning attributes after creating an object. The __init__() method will allow you to initialize an object’s data automatically at the time the object is created, making your classes cleaner and more practical.