Encapsulation in Python 🔐🐍

Encapsulation is one of the core principles of Object-Oriented Programming (OOP). It refers to restricting direct access to an object’s data and modifying it only through methods.
Python does not enforce strict access control like some other languages (e.g., Java, C++). Instead, it follows a naming convention to indicate access levels.
1️⃣ Access Modifiers in Python
Python provides three types of access control:
Modifier Naming Convention Access Level Example
Public variable_name Accessible anywhere self.name = "Alice"
Protected _variable_name (single underscore) Accessible within the class and subclasses self._age = 25
Private __variable_name (double underscore) Accessible only inside the class (Name Mangling applies) self.__salary = 5000
2️⃣ Public Members (No Underscore)
📌 Public members are accessible from anywhere – inside and outside the class.
class Person:
def __init__(self, name):
self.name = name # Public attribute
def display(self):
return f"My name is {self.name}" # Public method
person = Person("Alice")
print(person.name) # ✅ Allowed (Public)
print(person.display()) # ✅ Allowed (Public)
🔹 name is public, so it can be accessed directly.
🔹 Not recommended to expose critical data as public.
3️⃣ Protected Members (Single Underscore _var)
📌 Protected members are not strictly enforced but are meant to be accessed only within the class or subclasses.
class Person:
def __init__(self, name, age):
self.name = name # Public
self._age = age # Protected (Single underscore)
def display(self):
return f"Name: {self.name}, Age: {self._age}"
class Employee(Person):
def __init__(self, name, age, salary):
super().__init__(name, age)
self.salary = salary
def show_details(self):
return f"{self.display()}, Salary: {self.salary}"
emp = Employee("Bob", 30, 5000)
print(emp._age) # ✅ Allowed but discouraged
print(emp.show_details())
🔹 _age is protected, so it should only be accessed within the class or subclass.
🔹 Not enforced, but it is a convention not to access it directly outside the class.
4️⃣ Private Members (Double Underscore __var)
📌 Private members cannot be accessed directly outside the class.
class BankAccount:
def __init__(self, account_holder, balance):
self.account_holder = account_holder # Public
self.__balance = balance # Private (Double underscore)
def deposit(self, amount):
self.__balance += amount
return f"New balance: {self.__balance}"
def get_balance(self):
return f"Balance: {self.__balance}" # Accessing private data inside class
account = BankAccount("Alice", 1000)
# print(account.__balance) ❌ AttributeError (Private)
print(account.get_balance()) # ✅ Accessed via method
🔹 __balance is private, meaning it cannot be accessed directly.
🔹 Use getter methods (get_balance()) to access private attributes safely.
5️⃣ Name Mangling (_ClassName__var) – Accessing Private Members
📌 Python performs name mangling to make private variables unique to avoid accidental modification.
print(account._BankAccount__balance) # ✅ Allowed via name mangling
🚨 But modifying private attributes directly is discouraged.
6️⃣ Getters & Setters for Encapsulation
📌 Best practice: Use getter and setter methods to control access to private data.
class Employee:
def __init__(self, name, salary):
self.name = name
self.__salary = salary # Private
# Getter method
def get_salary(self):
return self.__salary
# Setter method
def set_salary(self, new_salary):
if new_salary > 0:
self.__salary = new_salary
else:
raise ValueError("Salary must be positive")
emp = Employee("John", 5000)
print(emp.get_salary()) # ✅ Access via getter
emp.set_salary(6000) # ✅ Modify via setter
print(emp.get_salary())
# emp.__salary = 10000 ❌ Does not change private variable
🔹 Getters (get_salary()) allow safe access to private attributes.
🔹 Setters (set_salary()) validate and modify private attributes.
7️⃣ Summary Table
Modifier Convention Access Example
Public variable_name Accessible anywhere self.name
Protected _variable_name Meant for class & subclasses self._age
Private __variable_name Accessible only inside class (Name Mangling applies) self.__balance
Name Mangling _ClassName__variable_name Used to access private variables manually _BankAccount__balance
Encapsulation Best Practice Use getters & setters for private attributes get_salary(), set_salary()
8️⃣ When to Use Encapsulation?
✅ To prevent direct modification of sensitive data.
✅ To implement data validation using setters.
✅ To maintain code flexibility while restricting access.