Encapsulation
What is Encapsulation in Python?
• Encapsulation is a fundamental object-oriented principle in Python. It protects your
classes from accidental changes or deletions and promotes code reusability and
maintainability.
• Encapsulation in Python describes the concept of bundling data and methods
within a single unit.
• A class is an example of encapsulation as it binds all the data members (
instance variables) and methods into a single unit.
• It allows you to restrict direct access to some of the object’s components, which
helps protect the integrity of the data.
• For example, imagine a bank account. The balance in your account should only be
changed by specific actions, such as deposits or withdrawals, not directly by
anyone accessing the balance. By encapsulating the balance inside the class and
providing controlled access through methods (deposit, withdraw), you ensure that
the balance cannot be tampered with directly.
Access Modifiers in Python Encapsulation
• In Python, access modifiers control the visibility and accessibility of attributes
and methods within a class. By using access modifiers, you can restrict access to
certain parts of your code and ensure data integrity.
• There are three main types of access modifiers in Python:
Public Member: Accessible anywhere from otside oclass.
Private Member: Accessible within the class
Protected Member: Accessible within the class and its sub-classes
Public Access Specifier:
• Public attributes and methods are accessible from anywhere, both inside and
outside the class. These are the default type of attributes and methods if no
access modifier is specified.
• Example:You can create a public method or attribute by simply defining it
without
classany prefix:
Employee:
# constructor
def __init__(self, name, salary):
• # public data members
[Link] = name
[Link] = salary
# public instance methods
def show(self):
# accessing public data member
print("Name: ", [Link], 'Salary:', [Link])
# creating object of a class
emp = Employee('Jessa', 10000)
# accessing public data members
print("Name: ", [Link], 'Salary:', [Link])
# calling public method of the class
[Link]()
Private Member:
• We can protect variables in the class by marking them private. To define a private
variable add two underscores as a prefix at the start of a variable name.
• Private members are accessible only within the class, and we can’t access them
directly from the class objects.
class Employee:
# constructor
def __init__(self, name, salary):
# public data member
[Link] = name
# private member
self.__salary = salary
# creating object of a class
emp = Employee('Jessa', 10000)
# accessing private data members
print('Salary:', emp.__salary)
AttributeError: 'Employee' object has no attribute '__salary'
• We can access private members from outside of a class using the
following two approaches
• Create public method to access private members
• Use name mangling
• Public method to access private members
• Example: Access Private member outside of a class using an instance
method
class Employee:
# constructor
def __init__(self, name, salary):
# public data member
[Link] = name
# private member
self.__salary = salary
# public instance methods
def show(self):
# private members are accessible from a class
print("Name: ", [Link], 'Salary:', self.__salary)
# creating object of a class
emp = Employee('Jessa', 10000)
# calling public method of the class
[Link]()
Name Mangling to access private members:
• We can directly access private and protected variables from
outside of a class through name mangling.
• The name mangling is created on an identifier by adding two
leading underscores and one trailing underscore, like this
• _classname__dataMember
• where classname is the current class, and data member is
the private variable name.
Name Mangling to access private members:
• Example: Access private member
class Employee:
# constructor
def __init__(self, name, salary):
# public data member
[Link] = name
# private member
self.__salary = salary
# creating object of a class
emp = Employee('Jessa', 10000)
print('Name:', [Link])
# direct access to private member using name mangling
print('Salary:', emp._Employee__salary)
Protected Member:
• Protected members are accessible within the class and also available to its sub-
classes. To define a protected member, prefix the member name with a single
underscore _.
• Protected data members are used when you implement inheritance and want to
allow data members access to only child classes.
# base class
class Company: def __init__(self):
# Protected member
self._project = "NLP"
# child class
class Employee(Company):
OUTPUT:
def __init__(self, name):
[Link] = name Employee name : Jessa
Company.__init__(self)
Working on project : NLP
def show(self):
print("Employee name :", [Link]) Project: NLP
# Accessing protected member in child class
print("Working on project :", self._project)
c = Employee("Jessa")
[Link]()
# Direct access protected data member
print('Project:', c._project)
Getters and Setters in Python:
• To implement proper encapsulation in Python, we need to use setters and
getters.
• The primary purpose of using getters and setters in object-oriented programs
is to ensure data encapsulation. Use the getter method to access data members
and the setter methods to modify the data members.
• In Python, private variables are not hidden fields like in other programming
languages. The getters and setters methods are often used when:
• When we want to avoid direct access to private variables
• To add validation logic for setting a value
Example:
class Student:
def __init__(self, name, age):
# private member
[Link] = name
self.__age = age
# getter method
def get_age(self):
return self.__age
# setter method
def set_age(self, age):
self.__age = age
stud = Student('Jessa', 14)
# retrieving age using getter
print('Name:', [Link], stud.get_age())
# changing age using setter
stud.set_age(16)
# retrieving age using getter
print('Name:', [Link], stud.get_age())
Example: Information Hiding and conditional logic for setting an
object attributes
class Student: correct roll number')
def __init__(self, name, roll_no, else: self.__roll_no = number
age):
# private member
[Link] = name
# private members to restrict jessa = Student('Jessa', 10, 15)
access # avoid direct data modification # before Modify
self.__roll_no = [Link]()
roll_no # changing roll number using setter
self.__age = age jessa.set_roll_no(120)
def show(self): jessa.set_roll_no(25)
print('Student Details:', [Link]()
[Link], self.__roll_no)
# getter methods
def get_roll_no(self):
return self.__roll_no
# setter method to modify data member
# condition to allow data
modification with rules
def set_roll_no(self, number):
if number > 50:
print('Invalid roll
no. Please set
Advantages of Encapsulation:
• Security: The main advantage of using encapsulation is the security of
the data. Encapsulation protects an object from unauthorized access. It
allows private and protected access levels to prevent accidental data
modification.
• Data Hiding: The user would not be knowing what is going on behind the
scene. They would only be knowing that to modify a data member, call the
setter method. To read a data member, call the getter method. What these
setter and getter methods are doing is hidden from them.
• Simplicity: It simplifies the maintenance of the application by keeping
classes separated and preventing them from tightly coupling with each
other.
• Aesthetics: Bundling data and methods within a class makes code more
readable and maintainable