January 19, 2021

Encapsulation in Python With Examples

In this post we’ll see the usage of OOPS concept Encapsulation in Python.

What is Encapsulation

Encapsulation is the process of keeping the data and the code (methods) that manipulates that data together as a unit. Any variable can only be changed through a method in the same class that way data is protected from any intentional or accidental modification by any outside entity.

A class is an example of encapsulation as it wraps all the variables and methods defined with in that class.

Encapsulation in Python

Since class is an example of Encapsulation so defining a class in Python which wraps all the variables and methods is first step towards encapsulation. But the question is how to stop outside access to the variables as there are no explicit access modifiers like public, private, protected in Python and all the variables are public by default. Here is an example to clarify it-

class User:
  def __init__(self, name, age):
    self.name = name
    self.age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user.age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
34

As you can see name and age fields of the class User can be accessed through a class method as well as directly outside the class too.

How to control access in Python

As demonstrated through an example class fields can be accessed directly from outside the class in Python so how to control that access and how to have proper encapsulation in Python?

Python has the concept of using a variable prefixed with a single underscore (e.g. _name) and a variable prefixed with double underscores (e.g. __name) to give some semblance to controlling access with in a class.

Using single underscore

Prefixing a variable with a single underscore is merely a convention followed in Python code to show your intention that such a class member should be treated as a non-public part of the API (whether it is a function, a method or a data member). It is more of an indicator to other developers that such a class member should be used only with in the scope of the class and shouldn’t be accessed from outside the class.

Since using a single underscore is just a convention so it doesn’t actually change the access of the variable in any way.

class User:
  def __init__(self, name, age):
    self.name = name
    self._age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self._age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user._age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
34

You can see that the age variable is now prefixed with a single underscore but that can still be accessed outside the class. You will get this warning though ‘Access to a protected member _age of a class’.

Using double underscore

You can come closest to making a class member private in Python by prefixing it with double underscores. This process is known as name mangling in Python where any identifier of the form __var (at least two leading underscores, at most one trailing underscore) is textually replaced with _classname__var by the Python interpreter, where classname is the current class name.

class User:
  def __init__(self, name, age):
    self.name = name
    self.__age = age

  def display_user(self):
    print('User Name:', self.name)
    print('User Age:', self.__age)


user = User('Mike Dallas', 34)
# calling class method
user.display_user()
# Accessing variables directly
print(user.name)
print(user.__age)
Output
User Name: Mike Dallas
User Age: 34
Mike Dallas
Traceback (most recent call last):
  File "F:/knpcode/Programs/Example.py", line 16, in 
    print(user.__age)
AttributeError: 'User' object has no attribute '__age'

Now the age variable is prefixed with double underscores which changes its name internally to _User__age thus it is not accessible from outside the class. From the method with in the class it is still accessible.

Note that using double underscores just change the name of the field so it is still possible to access or modify a variable that is considered private by using the changed name.

In the example you can change statement print(user.__age) to print(user._User__age) to access the changed name directly.

That's all for the topic Encapsulation in Python With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

No comments:

Post a Comment