Encapsulation in Python

Encapsulation, along with abstraction, inheritance, and polymorphism, is a fundamental concept in object-oriented programming (OOP).

In this post, let us look at what is encapsulation with the examples to understand it more clearly.

Encapsulation

Encapsulation is the process of wrapping up variables and methods into a single entity. It is a fundamental idea in object-oriented programming (OOP). It works as a protective shield, limiting direct access to variables and methods and preventing accidental or unauthorized data alteration. Encapsulation also turns objects into more self-sufficient, self-contained (independently functioning)units.

Real-time Example

Consider the following real-world example of encapsulation. A company has various sections, such as the accounts and finance sections. The finance department controls all financial transactions and data. The sales department is also in charge of all sales-related activities. They keep track of every sale. A finance officer may require full sales data for a certain month at times. He is not permitted to see the data from the sales area in this case. He must first call another officer in the sales unit to request the data. This is called encapsulation.

Access Modifiers in Encapsulation

While programming, it may be necessary to restrict or limit access to particular variables or functions. This is where access modifiers come into play.

When it comes to access, there are three types of access specifiers that can be utilised while executing Encapsulation in Python. They are:

  • Public Members
  • Private Members
  • Protected Members

Public Members

Members of the public can be accessed from anywhere from a class. By default, all of the class variables are public.

Approach:

  • Create a class say employDetails
  • Create a __init_ constructor which accepts employName and employId as arguments
  • Create public data members inside the class.
  • Create a function say displayEmployId which prints the employ id when it is called
  • Access the public data member of the class and print the result
  • Create an object of the class employDetails
  • Access the public data member of the class and print the result
  • Call the public member function displayEmployId of the class employDetails.
  • The Exit of the Program.

Below is the implementation:

# create a class say employDetails
class employDetails:

    # Create a __init_ constructor which accepts employName and employId as arguments 
    def __init__(self, employName, employId):
        # create public data members
        self.employName = employName;
        self.employId = employId;

    # Create a function say displayEmployId which prints 
    # the employ id when it is called
    def displayEmployId(self): 
        # Access the public data member of the class and print the result
        print("employId: ", self.employId)

# create an object of the class employDetails
employdetails_obj = employDetails("John", 2122);

# Access the public data member of the class and print the result
print("employName: ", employdetails_obj.employName)  

# call the public member function displayEmployId of the class employDetails
employdetails_obj.displayEmployId()

Output:

employName: John
employId: 2122

The variable employName and employId are both public in class employDetails. These data members are available throughout the program.

Private Members

Private members are accessible within the class. To define a private member, use a double underscore “__” before the member name.

Private members and protected members are the same thing. The difference is that private class members should not be accessed by anyone outside the class or its base classes. Private instance variable variables that can be accessed outside of a class do not exist in Python.

Python’s private and secured members can be accessed from outside the class by renaming them.

Approach:

  • Create a class say employDetails
  • Create a __init_ constructor which accepts employName and employId as arguments
  • Create a public variable inside the class
  • Create private variable prefixed with “__” inside the class
  • Create an object of the class employDetails and call it.
  • Access the public variable name of the class and print the result.
  • Access the private data variable __employId of the class employDetails and print the result.
  • The Exit of the Program.

Below is the implementation:

# create a class say employDetails
class employDetails:
   
   # Create a __init_ constructor which accepts employName and employId as arguments 
   def __init__(self, employName, employId):
      # Create a public variable
      self.employName = employName
      # Create private variable prefixed with "__"
      self.__employId = employId

# create an object of the class employDetails and call it
employdetails_obj = employDetails("John", 2122)

# Access the public variable name of the class and print the result
print("employName:",employdetails_obj.employName)

# Access the private data variable __employId of the class employDetails and print the result
print("employId:",employdetails_obj._employDetails__employId)

Output:

employName: John
employId: 2122

__employId is a private variable in class employDetails; thus, it is accessed by creating an object/instance.

Protected Members

Protected members can be accessed both within the class and by its subclasses. To define a protected member, use a single underscore “_” before the member name.

The protected variable can be accessed from the class and in derived classes (it can even be updated in derived classes), but it is not usually accessed outside of the class body.

The __init__ method(constructor), runs when an object of a type is instantiated.

# create a class say employDetails
class employDetails:
    # Creat which accepts employName and employId as arguments  
    def __init__(self, employName, employId):
        # protected data members as they are prefixed with single underscore "_"
        self._employName = employName
        self._employId = employId

# create object of the class employDetails and call it 
employdetails_obj = employDetails("John", 2122)

# Access the protected members of the class and print the result
print("employName:",employdetails_obj._employName)
print("employId:",employdetails_obj._employId)

Output:

employName: John
employId: 2122

Advantages of Encapsulation

1)Encapsulation ensures that code is well-defined and readable.

The fundamental benefit of using Encapsulation in Python is that as users, we do not need to understand the architecture of the functions and data and can instead focus on using these functional, encapsulated units in our applications. As a result, the code is more organized and clean. The user experience also improves significantly, making it easier to comprehend apps as a whole.

2)Encapsulation Prevents Accidental Modification/Deletion

Another advantage of encapsulation is that it protects data and methods from being accidentally modified. Consider the NumPy example again: if I had access to the library, I might introduce a mistake in the implementation of the mean function, and as a result, millions of NumPy projects would become incorrect.

3)Encapsulation ensures security

Python encapsulation is achieved with access modifiers. These access modifiers ensure that access conditions are not violated, resulting in a positive user experience in terms of security.