Python

Understanding Encapsulation in Python

Understanding Encapsulation in Python

Introduction

In Object-Oriented Programming (OOP), encapsulation is the concept of wrapping data, and the methods to work as a single cell on the data. Now by doing this, it put restrictions to access variables and methods directly and also can save us from the accidental modification of data. To prevent this change, we can only change an object’s variable by the object’s method. These types of variables are called private variables. A class can be an example of encapsulation, as it encapsulates all the data like variables, members functions, subclasses, etc.

A real-life example of encapsulation

Now let us see an example of real life. Suppose there is a company that consists of many sections like finance section, sales section, accounts section, etc. All sections have their role to play. The finance section handles the finance work of the company and the sales section maintains the sales works of the company. Someday the finance section needs the records of the sales section. Now the finance section can not directly just access the records of the sales section. So in that case, the finance section will ask one o the agents from the sales section to let them access some records that were needed by the finance section. Now, this is what encapsulation i. Here the sales records and the agents working in that section are wrapped in a single unit named as sales section. Also using encapsulation, we can hide data, as in the above example we can see that the employees of the finance section can not access the records or the sales section. So in this section data of a section is hidden from other sections.

Protected members

In Java and C++, the members can not be accessed outside of the class but can be accessed in the class and the subclasses in which it was declared. Now to accomplish this in python, we need to follow a convention, that is by prefixing the member with a single underscore ‘_’.

But this protected variable can be accessed out of the class and also can be accessed in the derived class. It is not a rule but a convention, that not to access the protected class body.

As soon the object of the init method is instantiated the constructor runs. By the way __init__method is a constructor.

Code

class B:

    def __init__(self):

        self._a = 2

 

class D(B):

    def __init__(self):

        B.__init__(self)

        print("Calling protected member: ",

              self._a)

        self._a = 3

        print("Calling modified protected: ",

              self._a)

 

o1 = D()

 

o2 = B()

 

print("Accessing protected member of obj1: ", o1._a)

 

print("Accessing protected member of obj2: ", o2._a)

write your code here: Coding Playground

Output

Calling modified protected:  3

Accessing protected member of o1:  3

Accessing protected member of o2:  2

Private members

In Python, private members are very much like protected members, now the difference between them is the class members of the class declare private can not be accessed outside the class. They also can not be accessed in any of the base classes. In Python, a private instance does not exist, because there is no way that an instance can be private and cannot be accessed. But if you want to declare a member private prefix that member name is with a double “__”.

Code

class C:

def __init__(self):

self.a = "Board Infinity"

self.__c = "Infinite"


class D(C):

def __init__(self):

C.__init__(self)

print("Calling private member of base class: ")

print(self.__c)



# Driver code

obj = C()

print(obj.a)

# If we uncomment print(obj.c), it will

# raise an AttributeError

 

# If we uncomment obj2 = Derived(), it will

# raise an AtrributeError because

# private member of base class

# is called inside derived class

write your code here: Coding Playground

Output

Board Infinity

Uncommenting obj.c

class C:

def __init__(self):

self.a = "Board Infinity"

self.__c = "Infinite"


class D(C):

def __init__(self):

C.__init__(self)

print("Calling private member of base class: ")

print(self.__c)



# Driver code

obj = C()

print(obj.a)

print(obj.c)

 

# obj2 = Derived()

write your code here: Coding Playground

Output

Board Infinity

Traceback (most recent call last):

  File "main.py", line 16, in <module>

    print(obj.c)

AttributeError: 'C' object has no attribute 'c'

Uncommenting obj2

class C:

def __init__(self):

self.a = "Board Infinity"

self.__c = "Infinite"


class D(C):

def __init__(self):

C.__init__(self)

print("Calling private member of base class: ")

print(self.__c)


# Driver code

obj = C()

print(obj.a)

# print(obj.c)

obj2 = Derived()

write your code here: Coding Playground

Output

Board Infinity

Traceback (most recent call last):

  File "main.py", line 18, in <module>

    obj2 = Derived()

NameError: name 'Derived' is not defined