Introduction
Encapsulation is one of the four fundamental pillars of Object-Oriented Programming (OOP), along with Inheritance, Polymorphism, and Abstraction. It is a mechanism that bundles data (attributes) and methods (functions) into a single unit called a class while restricting direct access to certain parts of the object.
For example, consider a bank account. The account balance should not be modified directly by anyone. Instead, users should deposit or withdraw money through specific methods. This ensures that the balance remains valid and secure.
What is Encapsulation in Python?
Encapsulation is the process of wrapping data and methods together into a single unit (class) and restricting direct access to certain data.
- Protect data from unauthorized access
- Improve code security
- Maintain data integrity
- Provide controlled access through methods
Example:
class Student:
def __init__(self):
self.name = "John"
Here:
- Data (name) and behavior (methods) belong to the same class.
- This is a basic example of encapsulation.
Real-Life Example of Encapsulation
Think about an ATM machine.
You can:
- Check balance
- Withdraw money
- Deposit money
You cannot:
- Directly modify the bank database
- Change account balances manually
The ATM provides controlled access to account information.
Similarly, encapsulation controls how object data is accessed and modified.
Syntax
Basic example:
class Student:
def __init__(self):
self.name = "John"
def display(self):
print(self.name)
Usage:
student = Student()
student.display()
Output:
Access Modifiers in Python
Python does not have strict access modifiers like Java or C++, but it follows naming conventions to indicate access levels.
There are three types:
- Public Members
- Protected Members
- Private Members
1. Public Members
Public members can be accessed from anywhere.
Example:
class Student:
def __init__(self):
self.name = "John"
student = Student()
print(student.name)
Output:
Explanation:
The variable:
name
is public because it has no underscore prefix.
2. Protected Members
Protected members are intended to be accessed only within the class and its subclasses.
A single underscore (_) is used.
Example:
class Student:
def __init__(self):
self._name = "John"
student = Student()
print(student._name)
Output:
Explanation:
Python does not strictly enforce protection.
The underscore acts as a convention indicating:
“This member should not be accessed directly outside the class.”
3. Private Members
Private members are intended to be accessed only within the class.
A double underscore (__) is used.
Example:
class Student:
def __init__(self):
self.__name = "John"
Accessing:
student = Student()
print(student.__name)
Output:
Explanation:
Python performs name mangling to make direct access difficult.
Private Variables Example
class Student:
def __init__(self):
self.__name = "John"
def display(self):
print(self.__name)
student = Student()
student.display()
Output:
The private variable can be accessed through class methods.
Accessing Private Variables Using Methods
class Student:
def __init__(self):
self.__marks = 85
def get_marks(self):
return self.__marks
student = Student()
print(student.get_marks())
Output:
This is a common encapsulation practice.
Modifying Private Variables Through Methods
class Student:
def __init__(self):
self.__marks = 0
def set_marks(self, marks):
self.__marks = marks
def get_marks(self):
return self.__marks
student = Student()
student.set_marks(90)
print(student.get_marks())
Output:
This allows controlled updates.
Getter and Setter Methods
Getter and Setter methods are commonly used to implement encapsulation.
Getter
Returns a value.
def get_marks(self):
return self.__marks
Setter
Updates a value.
def set_marks(self, marks):
self.__marks = marks
These methods provide controlled access to private data.
Encapsulation with Validation
One major advantage of encapsulation is data validation.
Example:
class BankAccount:
def __init__(self):
self.__balance = 0
def deposit(self, amount):
if amount > 0:
self.__balance += amount
def get_balance(self):
return self.__balance
account = BankAccount()
account.deposit(500)
print(account.get_balance())
Output:
Invalid values can be rejected before updating data.
Real-Life Example: Bank Account System
class BankAccount:
def __init__(self, balance):
self.__balance = balance
def deposit(self, amount):
self.__balance += amount
def withdraw(self, amount):
if amount <= self.__balance:
self.__balance -= amount
def get_balance(self):
return self.__balance
account = BankAccount(1000)
account.deposit(500)
account.withdraw(300)
print(account.get_balance())
Output:
Benefits:
- Balance remains protected.
- Direct modification is prevented.
- Transactions occur through methods.
Real-Life Example: Employee Management System
class Employee:
def __init__(self, salary):
self.__salary = salary
def get_salary(self):
return self.__salary
employee = Employee(50000)
print(employee.get_salary())
Output:
The salary remains private and secure.
Name Mangling in Python
Python internally changes private variable names.
Example:
class Student:
def __init__(self):
self.__name = "John"
Internally:
_Student__name
Python uses this technique to prevent accidental access.
Example:
student = Student()
print(student._Student__name)
Output:
Although possible, direct access like this is not recommended.
Encapsulation vs Data Hiding
Many developers confuse these concepts.
| Encapsulation | Data Hiding |
|---|---|
| Bundles data and methods | Restricts data access |
| Achieved using classes | Achieved using private members |
| Improves organization | Improves security |
| Broader concept | Part of encapsulation |
Data hiding is one aspect of encapsulation.
Advantages of Encapsulation
| Advantage | Description |
|---|---|
| Reusability | Well-structured code |
| Flexibility | Internal implementation can change |
| Better Control | Access through methods |
| Data Security | Protects sensitive information |
| Maintainability | Easier updates and debugging |
Common Mistakes
1. Accessing Private Variables Directly
Incorrect:
student.__name
Correct:
student.get_name()
2. Making Everything Public
Incorrect:
self.balance
for sensitive data.
Better:
self.__balance
3. Skipping Validation
Incorrect:
self.__age = age
Better:
if age > 0:
self.__age = age
4. Overusing Private Variables
Not every variable needs to be private.
Use private members only when protection is necessary.
5. Ignoring Getter and Setter Methods
Always provide controlled access when working with private data.
Conclusion
Encapsulation is a fundamental Object-Oriented Programming concept that helps protect data and maintain code integrity. By combining attributes and methods within a class and restricting direct access to sensitive data, encapsulation improves security, flexibility, and maintainability.
Python supports encapsulation through public, protected, and private members, along with getter and setter methods for controlled access. Whether you’re building banking systems, employee management software, e-commerce platforms, or web applications, understanding encapsulation is essential for writing professional, secure, and scalable Python code.
Python Encapsulation – Interview Questions
Q 1: What is encapsulation in Python?
Q 2: How are private attributes defined?
Q 3: How can private attributes be accessed?
Q 4: Why is encapsulation important?
Q 5: Are Python attributes truly private?
Python Encapsulation – Objective Questions (MCQs)
Q1. What is encapsulation in Python?
Q2. Which of the following symbols is used to make an attribute private in Python?
Q3. What is the output of the following code?
class Test:
def __init__(self):
self.__x = 10
obj = Test()
print(obj.__x)
Q4. How can you access a private variable outside the class (not recommended)?
Q5. Which of the following is a correct example of encapsulation?