Tutorial Playlist
Python is a versatile and popular programming language known for its simplicity and readability. It's also an object-oriented programming (OOP) language and leverages concepts like classes and objects to structure and organize code. One of the fundamental principles of OOP is encapsulation. This article covers what is encapsulation in python, why it's important, how it is implemented, encapsulation real-time examples and more.
Encapsulation is a foundational concept that involves bundling data and methods into classes. The primary goal of encapsulation is to hide the internal details of how a class works and provide a clear, well-defined interface for interacting with it.
Encapsulation in Python refers to the practice of bundling data (attributes) and methods (functions) that operate on that data into a single unit called a class. In simpler terms, encapsulation can be compared to packaging items in a box. The box holds various items, protects them and provides a convenient way to access them. Similarly, a class in Python encapsulates data and the functions that manipulate data, creating a self-contained unit within which the data is protected from external interference.
Here is a class called Student that stores their name, age, and grade. With Encapsulation, these data attributes are protected within the class and can only be accessed and modified through well-defined methods.
class Student:
def __init__(self, name, age, grade):
self._name = name # Protected attribute
self._age = age # Protected attribute
self._grade = grade # Protected attribute
# Getter method
def get_name(self):
return self._name
# Setter method
def set_grade(self, grade):
if 0 <= grade <= 100:
self._grade = grade
# Create a Student object
student1 = Student("Alice", 18, 90)
# Accessing attributes through methods
print(student1.get_name()) # Output: "Alice"
# Modifying attributes through methods
student1.set_grade(95)
Encapsulation in Python is essential for several reasons like it protects the internal data of a class from unauthorized access and modification.
Encapsulation in python real time example:
Consider a class representing a bank account:
class BankAccount:
def __init__(self, account_number):
self._account_number = account_number # Protected attribute
def __validate_pin(self, pin):
return len(str(pin)) == 4
In this encapsulation example in Python, the _account_number attribute is protected and prevents direct modification from outside the class.
Encapsulation is implemented using access modifiers, which determine the visibility and accessibility of a class's members (attributes and methods) in Python.
The three access modifiers are as follows:
Let's see how these access modifiers work in practice.
Consider a class "Car" as an example:
class Car:
def __init__(self, make, model):
self.make = make # Public attribute
self.model = model # Public attribute
def start(self):
print(f"{self.make} {self.model} is starting.") # Public method
In this case, make and model attributes are public, and the start method is also public. They can be accessed directly from outside the class.
Now, let's explore how to use private members in Python:
class BankAccount:
def __init__(self, account_number):
self.__account_number = account_number # Private attribute
def __validate_pin(self, pin):
# Private method to validate the PIN
return len(str(pin)) == 4
In this data encapsulation in python example, the __account_number attribute and the __validate_pin method are marked as private using double underscores. They can be accessed within the class.
Name mangling is a technique in Python that allows you to access private members (attributes and methods marked with double underscores __) from outside the class by prefixing their names with the class name and an underscore (_ClassName__). It is used to make private members somewhat accessible but is generally discouraged to maintain encapsulation and code clarity.
Here's how it works:
class BankAccount:
def __init__(self, account_number):
self.__account_number = account_number # Private attribute
def __validate_pin(self, pin):
return len(str(pin)) == 4
# Creating an instance of the class
account = BankAccount("12345")
# Accessing private attributes using name mangling
print(account._BankAccount__account_number) # Output: 12345
# Accessing private method using name mangling
print(account._BankAccount__validate_pin(1234)) # Output: True
Protected members are accessible within the class itself and its subclasses, maintaining data integrity while allowing for some degree of flexibility. You indicate a member as protected by prefixing its name with a single underscore (_).
Here's an encapsulation in python example:
class Animal:
def __init__(self, name):
self._name = name # Protected attribute
def _make_sound(self, sound):
print(f"{self._name} makes a {sound} sound.") # Protected method
# Subclass of Animal
class Dog(Animal):
def bark(self):
self._make_sound("bark")
# Creating instances
animal = Animal("Generic Animal")
dog = Dog("Buddy")
# Accessing protected attribute
print(animal._name) # Output: Generic Animal
# Accessing protected method
dog.bark() # Output: Buddy makes a bark sound.
Let's explore a real-time example of data encapsulation in python. Consider a scenario where you're developing a class to manage employee data within a company.
Here's a simple encapsulation in python real time example:
class Employee:
def __init__(self, emp_id, emp_name, emp_salary):
self._emp_id = emp_id # Protected attribute
self._emp_name = emp_name # Protected attribute
self._emp_salary = emp_salary # Protected attribute
def get_employee_details(self):
"""Get employee details."""
return f"ID: {self._emp_id}, Name: {self._emp_name}, Salary: ${self._emp_salary}"
def increase_salary(self, amount):
"""Increase employee's salary."""
if amount > 0:
self._emp_salary = amount
else:
print("Invalid salary increase amount.")
def change_name(self, new_name):
"""Change employee's name."""
self._emp_name = new_name
# Create employee objects
employee1 = Employee(101, "Alice", 50000)
employee2 = Employee(102, "Bob", 60000)
# Access employee details
print(employee1.get_employee_details()) # Output: ID: 101, Name: Alice, Salary: $50000
# Increase employee salary
employee1.increase_salary(2000)
print(employee1.get_employee_details()) # Output: ID: 101, Name: Alice, Salary: $52000
# Change employee name
employee2.change_name("Eve")
print(employee2.get_employee_details()) # Output: ID: 102, Name: Eve, Salary: $60000
In this example, we have an Employee class that encapsulates employee data, including ID, name, and salary, along with methods to interact with this data. Here's how encapsulation benefits us in this scenario:
Following are the advantages of encapsulation in python:
Following are the disadvantages of encapsulation in Python:
1. Complexity: Overusing encapsulation can lead to code complexity and verbosity, making the code harder to understand.
Example: Extremely fine-grained encapsulation with numerous getters and setters can clutter the codebase.
2. Performance Overhead: Accessing data through methods can introduce a slight performance overhead compared to direct attribute access.
Example: In high-performance applications, frequent method calls for simple attribute access can impact speed.
3. Name Mangling: The use of name mangling to access private members can lead to less readable and maintainable code.
Example: Accessing private members using name mangling involves complex naming conventions and may confuse developers.
4. Limited Flexibility: Overly strict encapsulation can limit flexibility and make it challenging to extend or modify a class.
Example: If a class encapsulates data and operations too tightly, making changes in the class requires extensive modifications.
5. Complexity in Testing: Testing encapsulated code can be more complex, as you need to write additional test methods to access encapsulated data.
Example: In unit testing, you have to create extra methods to set encapsulated data for testing purposes.
Encapsulation in Python is a fundamental concept and OOP in general. It helps to create clean, organized, and secure code by encapsulating data and controlling access through different methods. It offers numerous advantages, but it's essential to use encapsulation judiciously to avoid unnecessary complexity.
Q1: What is the purpose of encapsulation in Python?
A1: The primary purpose is to protect data from unauthorized access and modification and provide a clear and controlled interface for interacting with a class.
Q2: Can I access private members of a class from outside using the name mangling?
A2: Yes, you can access private members using name mangling, but it's generally averted as it goes against the principle of encapsulation.
Q3: When should I use public, protected, or private members in Python?
A3: Use public members when the data should be accessible from anywhere, protected members when limited access is required within the class and its subclasses, and private members when data is encapsulated within the class.
Pavan Vadapalli
popular
Talk to our experts. We’re available 24/7.
Indian Nationals
1800 210 2020
Foreign Nationals
+918045604032
upGrad does not grant credit; credits are granted, accepted or transferred at the sole discretion of the relevant educational institution offering the diploma or degree. We advise you to enquire further regarding the suitability of this program for your academic, professional requirements and job prospects before enrolling. .