Encapsulation is about bundling data (attributes) and methods (functions that operate on the data) into a single unit, called a class. This unit keeps the data safe from outside interference and misuse.
In simple word we can say Encapsulation in programming is like putting something in a box with clear instructions on how to use it without needing to know what's inside.
Python uses naming conventions to indicate the level of access control for class members.
Public members are accessible from anywhere. In Python, all class members are public by default.
Example:
class Car:
def __init__(self, make, model):
self.make = make # Public attribute
self.model = model # Public attribute
def display_info(self):
return f"Car make: {self.make}, Model: {self.model}"
# Creating an instance of Car
car = Car("Toyota", "Camry")
print(car.display_info()) # Output: Car make: Toyota, Model: Camry
print(car.make) # Output: Toyota
print(car.model) # Output: Camry
Protected members are intended to be accessed only within the class and its subclasses. In Python, protected members are indicated by a single underscore ‘_’ prefix.
Example:
class Car:
def __init__(self, make, model):
self._make = make # Protected attribute
self._model = model # Protected attribute
def display_info(self):
return f"Car make: {self._make}, Model: {self._model}"
# Creating an instance of Car
car = Car("Toyota", "Camry")
print(car.display_info()) # Output: Car make: Toyota, Model: Camry
print(car._make) # Output: Toyota
print(car._model) # Output: Camry
Private members are intended to be accessed only within the class. In Python, private members are indicated by a double underscore ‘__’ prefix.
Example:
class Car:
def __init__(self, make, model):
self.__make = make # Private attribute
self.__model = model # Private attribute
def display_info(self):
return f"Car make: {self.__make}, Model: {self.__model}"
# Creating an instance of Car
car = Car("Toyota", "Camry")
print(car.display_info()) # Output: Car make: Toyota, Model: Camry
# Accessing private members directly will result in an error
# print(car.__make) # AttributeError: 'Car' object has no attribute '__make'
# print(car.__model) # AttributeError: 'Car' object has no attribute '__model'
Private members can be accessed through name mangling, where the member name is prefixed with _ClassName. However, this is not recommended as it breaks the encapsulation principle.
Example:
print(car._Car__make) # Output: Toyota
print(car._Car__model) # Output: Camry