Encapsulation is one of the fundamental pillars of Object-Oriented Programming (OOP). It describes the idea of wrapping data (attributes) and the methods that work on that data within a single unit, usually a Class.
Beyond just grouping things together, encapsulation is primarily about Information Hiding—restricting direct access to some of an object's components to prevent accidental modification or misuse.
Think of a Medicine Capsule. You know the medicine is inside, but you don't interact with the powder directly; you take the capsule. Similarly, a class acts as a protective container that keeps the internal data safe from external interference.
Unlike languages like Java or C++, Python does not have strict private or protected keywords. Instead, it uses a naming convention to signal how an attribute or method should be treated:
Public Members: Accessible from anywhere (inside or outside the class).
Syntax: name
Protected Members: Should not be accessed outside the class, except by sub-classes (Inheritance).
Syntax: _name (single underscore)
Private Members: Strictly accessible only within the class itself.
Syntax: __name (double underscore)
Data Security: Prevents external code from setting invalid values (e.g., setting a "bank_balance" to a negative number).
Flexibility: You can change the internal implementation of a class without affecting the code that uses the class.
Control: By using Getter and Setter methods, you can control exactly how data is read or modified.
In this example, we protect the __balance attribute so it cannot be changed directly from outside the class.
class BankAccount: def __init__(self, owner, balance): self.owner = owner # Public attribute self.__balance = balance # Private attribute (Double underscore) # Getter method: To see the balance def get_balance(self): return f"Account Balance: ${self.__balance}" # Setter method: To change the balance with validation def deposit(self, amount): if amount > 0: self.__balance += amount print(f"Successfully deposited ${amount}") else: print("Invalid deposit amount!") # Usage account = BankAccount("Arjun", 1000) print(account.owner) # Works (Public) # print(account.__balance) # Raises AttributeError (Private) print(account.get_balance()) # Accessing via a controlled method account.deposit(500)
When you use a double underscore __, Python performs "Name Mangling." It internally changes the name of the variable to _ClassName__variableName. While you can technically still access it this way, it is a strong signal that you shouldn't.
# Technically possible but highly discouraged:
print(account._BankAccount__balance)
| Access Level | Syntax | Description |
| Public | self.value | Accessible everywhere. |
| Protected | self._value | Accessible in Class and Sub-classes. (Gentleman's agreement) |
| Private | self.__value | Accessible only within the defined Class. |
Copyright ©2025. All Rights Reserved Emblab THE RAVE INNOVATION