Python Encapsulation Tutorial | Data Hiding, Access Modifiers, Getters & Setters
In real-world software applications, sensitive information such as passwords, bank account balances, employee salaries, and customer records should not be directly accessible or modifiable from outside the class. Encapsulation is one of the four pillars of Object-Oriented Programming (OOP) that helps protect data by restricting direct access and controlling how it is modified.
Python provides encapsulation through public, protected, and private members, along with getter and setter methods. Encapsulation improves security, prevents accidental data modification, and makes applications easier to maintain.
In this lesson, you’ll learn how encapsulation works, how to implement data hiding, use access modifiers, understand name mangling, and build secure Python applications using industry best practices.
By the end of this lesson, you’ll be able to design classes that protect sensitive data while exposing only the necessary functionality.
Learning Objectives
After completing this lesson, you will be able to:
- Understand the concept of encapsulation.
- Differentiate between public, protected, and private members.
- Implement data hiding in Python.
- Create getter and setter methods.
- Understand Python’s name mangling.
- Protect object data from unauthorized access.
- Apply encapsulation in real-world applications.
Topics Covered
- What is Encapsulation?
- Why Encapsulation is Important
- Public Members
- Protected Members
- Private Members
- Name Mangling
- Getter Methods
- Setter Methods
- Real-World Applications
- Best Practices
Detailed Lesson Content
Introduction to Encapsulation
Imagine you’re using a Banking Application.
As a customer, you can:
- Check your account balance.
- Deposit money.
- Withdraw money.
However, you cannot directly change your account balance by editing the bank’s database.
For example, you cannot simply write:
balance = 10000000
Instead, you must use approved methods like:
- Deposit
- Withdraw
- Transfer
This protection of data is called Encapsulation.
Encapsulation hides sensitive information and allows controlled access through methods.
What is Encapsulation?
Encapsulation is the process of binding data (variables) and methods (functions) into a single unit (class) while restricting direct access to sensitive information.
Benefits include:
- Data Security
- Better Control
- Code Maintainability
- Improved Reliability
- Reduced Errors
Why Do We Need Encapsulation?
Without encapsulation:
- Anyone can modify important data.
- Applications become insecure.
- Bugs increase.
- Business rules can be bypassed.
With encapsulation:
- Data remains protected.
- Only authorized methods can update values.
- Validation becomes easier.
- Software becomes more secure.
Public Members
Public members are accessible from anywhere.
Example:
class Student:
def __init__(self):
self.name = "Rahul"
student = Student()
print(student.name)
Output
Rahul
Public members have no underscore before the variable name.
Protected Members
Protected members begin with a single underscore (_).
Example:
class Student:
def __init__(self):
self._course = "Python"
student = Student()
print(student._course)
Output
Python
Protected members:
- Can still be accessed.
- Are intended for internal use.
- Follow a naming convention indicating they shouldn’t be accessed directly outside the class.
Private Members
Private members begin with double underscores (__).
Example
class BankAccount:
def __init__(self):
self.__balance = 50000
account = BankAccount()
print(account.__balance)
Output
AttributeError
Python prevents direct access to private members.
Name Mangling
Internally, Python changes private variable names.
Example
class Bank:
def __init__(self):
self.__balance = 10000
account = Bank()
print(account._Bank__balance)
Output
10000
This mechanism is called Name Mangling.
Although private variables can technically be accessed this way, it is strongly discouraged.
Getter Methods
Getter methods safely retrieve private data.
Example
class BankAccount:
def __init__(self):
self.__balance = 50000
def get_balance(self):
return self.__balance
account = BankAccount()
print(account.get_balance())
Output
50000
This is the recommended way to access private variables.
Setter Methods
Setter methods safely update private data.
Example
class BankAccount:
def __init__(self):
self.__balance = 50000
def set_balance(self,amount):
if amount >= 0:
self.__balance = amount
account = BankAccount()
account.set_balance(70000)
print(account.get_balance())
Output
70000
Notice how validation is applied before updating the value.
Real-World Example 1: Banking System
class BankAccount:
def __init__(self,name,balance):
self.name = name
self.__balance = balance
def deposit(self,amount):
self.__balance += amount
def withdraw(self,amount):
if amount <= self.__balance:
self.__balance -= amount
else:
print("Insufficient Balance")
def get_balance(self):
return self.__balance
account = BankAccount("Rahul",10000)
account.deposit(5000)
account.withdraw(2000)
print(account.get_balance())
Output
13000
Real-World Example 2: Employee Salary Management
class Employee:
def __init__(self,name,salary):
self.name = name
self.__salary = salary
def get_salary(self):
return self.__salary
def update_salary(self,salary):
if salary > 0:
self.__salary = salary
employee = Employee("Amit",50000)
employee.update_salary(60000)
print(employee.get_salary())
Real-World Example 3: Student Portal
class Student:
def __init__(self,name):
self.name = name
self.__marks = 0
def add_marks(self,marks):
if 0 <= marks <= 100:
self.__marks = marks
def view_marks(self):
return self.__marks
student = Student("Priya")
student.add_marks(95)
print(student.view_marks())
Real-World Example 4: E-Commerce Product
class Product:
def __init__(self,name,price):
self.name = name
self.__price = price
def set_price(self,price):
if price > 0:
self.__price = price
def get_price(self):
return self.__price
product = Product("Laptop",70000)
product.set_price(65000)
print(product.get_price())
Common Mistakes
Accessing Private Variables Directly
Incorrect
print(account.__balance)
Correct
print(account.get_balance())
No Validation in Setter
Incorrect
def set_balance(self,balance):
self.__balance = balance
Better
if balance >= 0:
Always validate data before updating.
Making Everything Public
Sensitive information should never be stored as public variables.
Best Practices
- Keep sensitive data private.
- Provide controlled access using getters and setters.
- Validate data before updating.
- Avoid exposing internal implementation details.
- Use meaningful method names.
- Keep business logic inside the class.
- Use encapsulation to improve security and maintainability.
Key Takeaways
- Encapsulation protects object data.
- Public members are accessible everywhere.
- Protected members are intended for internal use.
- Private members are hidden using double underscores.
- Getter methods retrieve private data.
- Setter methods update private data safely.
- Name mangling helps protect private members.
- Encapsulation improves application security and code quality.



