When working with an Object Oriented Programming language like Python, encapsulation in Python is one of the 4 important concepts to understand. The other three are inheritance, polymorphism, and abstraction.
What is Encapsulation?
When working with classes and dealing with sensitive data, providing global access to all the variables used within the program is not a good choice. Encapsulation offers a way for us to access the required variables without providing the program full-fledged access to any of those variables.
Updating, modifying, or deleting data from variables can be done through the use of methods that are defined specifically for the purpose. The benefit of using this approach to programming is improved control over the input data and better security.
What is Encapsulation in Python?
The concept of encapsulation is the same in all object-oriented programming languages. The difference is seen when the concepts are applied to particular languages.
Compared to languages like Java that offer access modifiers (public or private) for variables and methods, Python provides access to all the variables and methods globally.
Check the below demonstration of how variables can easily be accessed.
class Person: def __init__(self, name, age=0): self.name = name self.age = age def display(self): print(self.name) print(self.age) person = Person('Dev', 30) #accessing using class method person.display() #accessing directly from outside print(person.name) print(person.age)
Dev 30 Dev 30
Since we do not have access modifiers in Python, we will use a few different methods to control the access of variables within a Python program.
Methods to Control Access
There are multiple methods that are offered by Python to limit variable and method access across the program. Let’s go over the methods in detail.
Using Single Underscore
A common Python programming convention to identify a private variable is by prefixing it with an underscore. Now, this doesn’t really make any difference on the compiler side of things. The variable is still accessible as usual. But being a convention that programmers have picked up on, it tells other programmers that the variables or methods have to be used only within the scope of the class.
See the below example:
class Person: def __init__(self, name, age=0): self.name = name self._age = age def display(self): print(self.name) print(self._age) person = Person('Dev', 30) #accessing using class method person.display() #accessing directly from outside print(person.name) print(person._age)
Dev 30 Dev 30
It’s clear that the variable access is unchanged. But can we do anything to really make it private? Let’s have a look further.
Using Double Underscores
If you want to make class members i.e. methods and variables private, then you should prefix them with double underscores. But Python offers some sort of support to the private modifier. This mechanism is called Name mangling. With this, it is still possible to access the class members from outside it.
In Python, any identifier with __Var is rewritten by a python interpreter as _Classname__Var, and the class name remains as the present class name. This mechanism of changing names is called Name Mangling in Python.
In the below example, in Class person, the age variable is changed and it’s prefixed by leading double underscores.
class Person: def __init__(self, name, age=0): self.name = name self.__age = age def display(self): print(self.name) print(self.__age) person = Person('Dev', 30) #accessing using class method person.display() #accessing directly from outside print('Trying to access variables from outside the class ') print(person.name) print(person.__age)
Dev 30 Trying to access variables from outside the class Dev Traceback (most recent call last): File "Person.py", line 16, in <module> print(person.__age) AttributeError: 'Person' object has no attribute '__age'
You can observe that variables are still be accessed using methods, which is a part of the class. But you cannot access age directly from outside, as it is a private variable.
Using Getter and Setter methods to access private variables
If you want to access and change the private variables, accessor (getter) methods and mutators(setter methods) should be used, as they are part of Class.
class Person: def __init__(self, name, age=0): self.name = name self.__age = age def display(self): print(self.name) print(self.__age) def getAge(self): print(self.__age) def setAge(self, age): self.__age = age person = Person('Dev', 30) #accessing using class method person.display() #changing age using setter person.setAge(35) person.getAge()
Dev 30 35
Benefits of Encapsulation in Python
Encapsulation not only ensures better data flow but also protects the data from outside sources. The concept of encapsulation makes the code self-sufficient. It is very helpful in the implementation level, as it prioritizes the ‘how’ type questions, leaving behind the complexities. You should hide the data in the unit to make encapsulation easy and also to secure the data.
What is the need for Encapsulation in Python
The following reasons show why developers find the Encapsulation handy and why the Object-Oriented concept is outclassing many programming languages.
- Encapsulation helps in achieving the well-defined interaction in every application.
- The Object-Oriented concept focuses on the reusability of code in Python. (DRY – Don’t Repeat Yourself).
- The applications can be securely maintained.
- It ensures the flexibility of the code through a proper code organization.
- It promotes a smooth experience for the users without exposing any back-end complexities.
- It improves the readability of the code. Any changes in one part of the code will not disturb another.
- Encapsulation ensures data protection and avoids the access of data accidentally. The protected data can be accessed with the methods discussed above.
Encapsulation in Python is, the data is hidden outside the object definition. It enables developers to develop user-friendly experience. This is also helpful in securing data from breaches, as the code is highly secured and cannot be accessed by outside sources.
References: Python Classes and Private variables