What is Encapsulation in Python With Example

Encapsulation, in the realm of object-oriented programming, encompasses the practice of consolidating data and methods into a cohesive entity known as a class.

This principle serves to obscure the inner workings of an object, while offering an avenue to engage with and manipulate the object via its public interface.

In Python, encapsulation can be achieved using access modifiers. There are three access modifiers available in Python:

  • Public: Public members are accessible from anywhere, both inside and outside the class. By default, all members in a class are public.
  • Protected: Protected members are denoted by a single underscore (_) prefix. They can be accessed within the class and its subclasses. However, they are conventionally considered private and should not be accessed from outside the class or its subclasses.
  • Private: Private members are denoted by a double underscore (__) prefix. They cannot be accessed directly from outside the class. Python internally modifies the name of private members to avoid name clashes between different classes. Private members can only be accessed indirectly within the class.

Here’s an example that demonstrates encapsulation in Python:

class Car:
    def __init__(self):
        self.__max_speed = 200  # Private member
        self._current_speed = 0  # Protected member

    def accelerate(self, speed):
        self._current_speed += speed
        if self._current_speed > self.__max_speed:
            self._current_speed = self.__max_speed

    def get_speed(self):
        return self._current_speed

# Creating an instance of the Car class
my_car = Car()

# Accessing public method to accelerate the car

# Accessing public method to get the current speed
print(my_car.get_speed())  # Output: 50

# Trying to access private member directly
print(my_car.__max_speed)  # Raises AttributeError: 'Car' object has no attribute '__max_speed'

# Trying to access protected member directly
print(my_car._current_speed)  # Output: 50

In the example above, the Car class has a private member __max_speed and a protected member _current_speed.

The accelerate method allows increasing the current speed while checking if it exceeds the maximum speed. The get_speed method provides a way to retrieve the current speed.

Attempting to access the private member __max_speed directly outside the class raises an AttributeError.

However, the protected member _current_speed can be accessed outside the class, although it’s conventionally considered private and not intended for direct access.

What are 2 examples of encapsulation?

Here are two examples of encapsulation in Python:

Bank Account:

class BankAccount:
    def __init__(self, account_number, balance):
        self.__account_number = account_number  # Private member
        self.__balance = balance  # Private member

    def deposit(self, amount):
        self.__balance += amount

    def withdraw(self, amount):
        if amount <= self.__balance:
            self.__balance -= amount
            print("Insufficient funds")

    def get_balance(self):
        return self.__balance

# Creating an instance of the BankAccount class
account = BankAccount("123456789", 1000)

# Accessing public methods to deposit and withdraw

# Accessing public method to get the balance
print(account.get_balance())  # Output: 1300

# Trying to access private members directly
print(account.__account_number)  # Raises AttributeError: 'BankAccount' object has no attribute '__account_number'
print(account.__balance)  # Raises AttributeError: 'BankAccount' object has no attribute '__balance'

In this example, the BankAccount class encapsulates the account number and balance as private members.

The public methods deposit, withdraw, and get_balance provide a way to interact with the object while maintaining encapsulation.

The private members cannot be accessed directly from outside the class.


class Employee:
    def __init__(self, name, salary):
        self._name = name  # Protected member
        self._salary = salary  # Protected member

    def get_details(self):
        return f"Name: {self._name}, Salary: {self._salary}"

# Creating instances of the Employee class
employee1 = Employee("John Doe", 5000)
employee2 = Employee("Jane Smith", 6000)

# Accessing protected members indirectly through public method
print(employee1.get_details())  # Output: Name: John Doe, Salary: 5000
print(employee2.get_details())  # Output: Name: Jane Smith, Salary: 6000

# Trying to access protected members directly
print(employee1._name)  # Output: John Doe
print(employee2._salary)  # Output: 6000

In this example, the Employee class encapsulates the employee’s name and salary as protected members.

The get_details method allows accessing the details of an employee.

The protected members can be accessed indirectly through the public method or even directly from outside the class, although it’s conventionally considered private and not intended for direct access.

Please note that in Python, there is no strict enforcement of encapsulation like in some other programming languages.

The use of naming conventions with single and double underscores is a convention followed by programmers to indicate the intended access level of members.

Read More;

  • Dmytro Iliushko

    I am a middle python software engineer with a bachelor's degree in Software Engineering from Kharkiv National Aerospace University. My expertise lies in Python, Django, Flask, Docker, REST API, Odoo development, relational databases, and web development. I am passionate about creating efficient and scalable software solutions that drive innovation in the industry.

Leave a Comment