Encapsulation is one of the four fundamental OOPS concepts. The other three being Inheritance, Polymorphism, Abstraction
What is Encapsulation
The concept of Encapsulation is to keep together the implementation (code) and the data it manipulates (variables). Having proper encapsulation ensures that the code and data both are safe from misuse by outside entity. That is done by restricting access to the methods and variables and any change to the variables done only through methods.
Encapsulation in Python
In any object oriented language first step towards encapsulation is the class and encapsulation in Python also starts from a class as the class encapsulates the methods and variables. When a Python class is created it contains the methods and the variables. Since it’s the code in the methods that operates on the variables, in a properly encapsulated Python class, methods should define how member variables can be used.
But that’s where the things differ a bit in Python from a language like Java where we have access modifiers like public, private. In Python there are no explicit access modifiers and everything written with in the class (methods and variables) are public by default.
For example in the class Person there are two variables as you can see those variables are accessed through a method as well as directly.
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('John', 40) #accessing using class method person.display() #accessing directly from outside print(person.name) print(person.age)
Output
John 40 John 40
Access control in Python
If everything inside a class is public then how to have access control and how to have proper encapsulation in Python?
In Python though there are no explicit access modifiers but using underscores (_) you can make a variable private.
Using single underscore
Using a single leading underscore is merely a convention. A name prefixed with an underscore in Python (as example _name) should be treated as a non-public part of the API (whether it is a function, a method or a data member).
As mentioned it is just a convention and a leading underscore doesn’t actually make any variable or method private or protected. It’s just that if you see a variable or method with a leading underscore in Python code you should follow the convention that it should be used internally with in a class.
For example in class Person if age variable is changed and it is prefixed with underscore.
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('John', 40) #accessing using class method person.display() #accessing directly from outside print(person.name) print(person._age)
Output
John 40 John 40
As you can see these variables can still be accessed from outside the class.
Using double underscore (making it private)
If you really want to make a class member (member or variable) private in Python you can do it by prefixing a variable or method with double underscores. Here note that Python provides a limited support for private modifier using a mechanism called name mangling and it is still possible to access such class member from outside the class.
In Python any identifier of the form __var (at least two leading underscores, at most one trailing underscore) is rewritten by the Python interpreter in the
form _classname__var
, where classname is the current class name. This mechanism of name changing is known as name mangling in Python.
For example in class Person age variable is changed and it is prefixed with two leading 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('John', 40) #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
Output
John 40 Trying to access variables from outside the class John Traceback (most recent call last): File "Person.py", line 16, in <module> print(person.__age) AttributeError: 'Person' object has no attribute '__age'
As you can see variables can still be accessed using the method which is part of the class but age (which is a private variable) can’t be accessed directly from outside now.
Using getter and setter methods to access private variables
To access and change private variables accessor (getter) methods and mutator (setter methods) should be used which are part of the 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('John', 40) #accessing using class method person.display() #changing age using setter person.setAge(45) person.getAge()
Output
John 40 45
That's all for this topic Encapsulation in Python. If you have any doubt or any suggestions to make please drop a comment. Thanks!
>>>Return to Python Tutorial Page
Related Topics
You may also like-