Open In App

Encapsulation in Python

Last Updated : 24 Jul, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Encapsulation means hiding internal details of a class and only exposing what’s necessary. It helps to protect important data from being changed directly and keeps the code secure and organized.

Technically, encapsulation is an object-oriented programming principle where data (variables) and methods (functions) are bundled together in a class.

Encapsulation
Encapsulation

Why do we need Encapsulation?

  • Protects data from unauthorized access and accidental modification.
  • Controls data updates using getter/setter methods with validation.
  • Enhances modularity by hiding internal implementation details.
  • Simplifies maintenance through centralized data handling logic.
  • Reflects real-world scenarios like restricting direct access to a bank account balance.

Example of Encapsulation

Encapsulation in Python is like having a bank account system where your account balance (data) is kept private. You can't directly change your balance by accessing account database. Instead, bank provides you with methods (functions) like deposit and withdraw to modify your balance safely.

  • Private Data (Balance): Your balance is stored securely. Direct access from outside is not allowed, ensuring data is protected from unauthorized changes.
  • Public Methods (Deposit and Withdraw): These are the only ways to modify your balance. They check if your requests (like withdrawing money) follow the rules (e.g., you have enough balance) before allowing changes.

Access Specifiers in Python

Access specifiers define how class members (variables and methods) can be accessed from outside the class. They help in implementing encapsulation by controlling the visibility of data. There are three types of access specifiers:

types_of_access_modifier
Types of Access Modifiers

Let's discuss it one by one.

Public Members

Public members are variables or methods that can be accessed from anywhere inside the class, outside the class or from other modules. By default, all members in Python are public.

They are defined without any underscore prefix (e.g., self.name).

Example:

This example shows how a public attribute (name) and a public method (display_name) can be accessed from outside the class using an object.

Python
class Public:
    def __init__(self):
        self.name = "John"  # Public attribute

    def display_name(self):
        print(self.name)  # Public method

obj = Public()
obj.display_name()  # Accessible
print(obj.name)  # Accessible

Output
John
John

Explanation:

  • Public Attribute (name): This attribute is declared without any underscore prefixes. It is accessible from anywhere, both inside and outside of the class.
  • Public Method (display_name): This method is also accessible from any part of the code. It directly accesses the public attribute and prints its value.
  • Object (obj): An instance of Public is created, and the display_name method is called, demonstrating how public attributes and methods can be accessed directly.

Note: __init__ method is a constructor and runs as soon as an object of a class is instantiated.  

Protected members

Protected members are variables or methods that are intended to be accessed only within the class and its subclasses. They are not strictly private but should be treated as internal.

In Python, protected members are defined with a single underscore prefix (e.g., self._name).

Example:

This example shows how a protected attribute (_age) can be accessed within a subclass, demonstrating that protected members are meant for use within the class and its subclasses.

Python
class Protected:
    def __init__(self):
        self._age = 30  # Protected attribute

class Subclass(Protected):
    def display_age(self):
        print(self._age)  # Accessible in subclass

obj = Subclass()
obj.display_age()

Output
30

Explanation:

  • Protected Attribute (_age): Prefixed with a single underscore to indicate it’s protected. This is a convention in Python, not enforced it suggests limited access.
  • Subclass Access: subclass inherits from Protected and can access _age directly.
  • Method (display_age): Demonstrates that protected members are accessible within the class and its subclasses.

Private members

Private members are variables or methods that cannot be accessed directly from outside the class. They are used to restrict access and protect internal data.

In Python, private members are defined with a double underscore prefix (e.g., self.__salary). Python applies name mangling by internally renaming them (e.g., __salary becomes _ClassName__salary) to prevent direct access.

Example:

This example shows how a private attribute (__salary) is accessed within the class using a public method, demonstrating that private members cannot be accessed directly from outside the class.

Python
class Private:
    def __init__(self):
        self.__salary = 50000  # Private attribute

    def salary(self):
        return self.__salary  # Access through public method

obj = Private()
print(obj.salary())  # Works
#print(obj.__salary)  # Raises AttributeError

Output
50000

Explanation:

  • Private Attribute (__salary): Defined with double underscores to make it private. Python uses name mangling to restrict direct access.
  • Method (salary): A public method that safely returns the private attribute’s value.
  • Direct Access: Attempting obj.__salary raises an AttributeError, showing that private members can't be accessed directly.

Declaring Protected and Private Methods

In Python, you can control method access levels using naming conventions:

  • Use a single underscore (_) before a method name to indicate it is protected meant to be used within class or its subclasses.
  • Use a double underscore (__) to define a private method accessible only within class due to name mangling.

Note: Unlike other programming languages, Python does not enforce access modifiers like public, private or protected at the language level. However, it follows naming conventions and uses a technique called name mangling to support encapsulation.

Example:

This example demonstrates how a protected method (_show_balance) and a private method (__update_balance) are used to control access. The private method updates balance internally, while protected method displays it. Both are accessed via a public method (deposit), showing how Python uses naming conventions for encapsulation.

Python
class BankAccount:
    def __init__(self):
        self.balance = 1000

    def _show_balance(self):
        print(f"Balance: ₹{self.balance}")  # Protected method

    def __update_balance(self, amount):
        self.balance += amount             # Private method

    def deposit(self, amount):
        if amount > 0:
            self.__update_balance(amount)  # Accessing private method internally
            self._show_balance()           # Accessing protected method
        else:
            print("Invalid deposit amount!")
            
account = BankAccount()
account._show_balance()      # Works, but should be treated as internal
# account.__update_balance(500)  # Error: private method
account.deposit(500)         # Uses both methods internally

Output
Balance: ₹1000
Balance: ₹1500

Explanation:

  • _show_balance(): (Protected method) Accessible from outside, but intended for internal or subclass use.
  • __update_balance(): (Private method) Only accessible inside class due to name mangling.
  • deposit(): Public method that safely uses both private and protected methods.

Getter and Setter Methods

In Python, getter and setter methods are used to access and modify private attributes safely. Instead of accessing private data directly, these methods provide controlled access, allowing you to:

  • Read data using a getter method.
  • Update data using a setter method with optional validation or restrictions.

Example:

This example shows how to use a getter and a setter method to safely access and update a private attribute (__salary).

Python
class Employee:
    def __init__(self):
        self.__salary = 50000  # Private attribute

    def get_salary(self):    # Getter method
        return self.__salary

    def set_salary(self, amount):   # Setter method
        if amount > 0:
            self.__salary = amount
        else:
            print("Invalid salary amount!")

emp = Employee()
print(emp.get_salary())  # Access salary using getter

emp.set_salary(60000)   # Update salary using setter
print(emp.get_salary()) 

Output
50000
60000

Explanation:

  • __salary is a private attribute, so it can't be accessed directly from outside the class.
  • get_salary() is a getter method that safely returns the current salary.
  • set_salary(amount) is a setter method that updates the salary only if the amount is positive.
  • The object emp uses these methods to access and modify the salary while keeping the data protected.

Encapsulation in Python
Visit Course explore course icon
Next Article
Article Tags :
Practice Tags :

Similar Reads

pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy