0% found this document useful (0 votes)
36 views9 pages

Chapter 2 Encapsulation and Data Hiding

Chapter 2 covers encapsulation and data hiding in Object-Oriented Programming, emphasizing the importance of controlling access to data through public, protected, and private members. It explains how Python implements data hiding using naming conventions and access modifiers, alongside the use of getters and setters for controlled access to attributes. Additionally, the chapter discusses name mangling as a method to prevent accidental access to private variables and contrasts encapsulation with abstraction.

Uploaded by

hpatil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
36 views9 pages

Chapter 2 Encapsulation and Data Hiding

Chapter 2 covers encapsulation and data hiding in Object-Oriented Programming, emphasizing the importance of controlling access to data through public, protected, and private members. It explains how Python implements data hiding using naming conventions and access modifiers, alongside the use of getters and setters for controlled access to attributes. Additionally, the chapter discusses name mangling as a method to prevent accidental access to private variables and contrasts encapsulation with abstraction.

Uploaded by

hpatil
Copyright
© © All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

Chapter 2: Encapsulation & Data Hiding

2.1 Data Hiding and Access Modifiers – Public, Private, and Protected Members

What is Encapsulation?

Encapsulation is one of the fundamental principles of Object-Oriented Programming (OOP).


It is the process of wrapping the data (variables) and code acting on the data (methods)
together as a single unit. This concept is often compared to a capsule in the medical field,
where all the components are wrapped inside one container.

Benefits of Encapsulation:

1. Control over data: Encapsulation allows a class to control the accessibility and
modification of its fields.

2. Increased security: It hides the internal object details from the outside world.

3. Easier maintenance and flexibility: Changes to encapsulated code can be made with
minimal impact on other parts of the codebase.

4. Code reusability and modularity: Encapsulation encourages writing self-contained,


reusable code blocks.

Data Hiding in Python

Data Hiding refers to restricting access to the internal data or functionality of an object. This
is a key part of encapsulation. Python doesn’t have built-in access modifiers like other
languages (e.g., private, protected in Java/C++), but it achieves data hiding through naming
conventions and mechanisms like name mangling.

Python achieves data hiding primarily through name mangling and convention-based access
modifiers.
Access Modifiers in Python

Python has three types of access modifiers to restrict the access of class members:

Modifier Type Syntax Example Accessibility

Public self.name Accessible from anywhere

Protected self._name Should not be accessed outside class or subclass

Private self.__name Name mangling is applied, access limited

1. Public Members

• Members (variables or methods) declared without any underscore prefix.

• These are accessible anywhere, both within and outside the class.

class Car:

def __init__(self, brand):

self.brand = brand # public member

c = Car("Toyota")

print(c.brand) # Output: Toyota

Usage:

• Use public members when you want the attributes or methods to be freely
accessible and modifiable.

2. Protected Members

• Prefixed with a single underscore: _member.

• Indicates that the member is intended to be protected, i.e., used only within the
class and its subclasses.

• Not enforced by Python — it's a convention.


class Vehicle:

def __init__(self, brand):

self._brand = brand # protected member

class Car(Vehicle):

def display(self):

print(f"Brand: {self._brand}")

c = Car("Honda")

c.display() # Accessing protected member

print(c._brand) # Technically allowed but discouraged

Usage:

• Used when you want to restrict access, but still allow subclasses to access or override
the member.

3. Private Members

• Prefixed with double underscores: __member.

• Python uses name mangling to make these members less accessible.

class Secret:

def __init__(self):

self.__code = 1234 # private member

s = Secret()

# print(s.__code) # Raises AttributeError

print(s._Secret__code) # Access using name mangling

What is Name Mangling?

• Python internally changes the name of private variables by prefixing it with


_ClassName.

• This helps avoid accidental modification or access.


Usage:

• Use when you want to hide data and prevent subclass from modifying it.

Summary Table: Access Modifiers

Modifier Prefix Accessible in Class Accessible in Subclass Accessible Outside

Public None Yes Yes Yes

Protected -------- Yes Yes Not Recommended

Private ------- Yes No (via mangling only) No (via mangling)

2.2 Getters and Setters – Using Property Decorators (@property)

Getter:

A getter is a method used to access or retrieve the value of a private or protected attribute
of a class. It provides a controlled way to read the value without directly accessing the
variable.

Definition:
A getter is a method that gets (returns) the value of an instance variable, typically one that
is private (__variable) or protected (_variable).

Setter:

A setter is a method used to set or update the value of a private or protected attribute. It
often includes validation logic to ensure that the data being assigned is appropriate.

Definition:
A setter is a method that sets (modifies) the value of an instance variable, ensuring proper
encapsulation and validation.
Why use Getters and Setters?

• Direct access to class attributes breaks encapsulation.

• Getters and Setters control access to private data.

• They allow validation, logging, or triggers during getting/setting values.

Traditional Getters and Setters in Python

class Person:

def __init__(self, age):

self.__age = age

def get_age(self):

return self.__age

def set_age(self, value):

if value > 0:

self.__age = value

else:

raise ValueError("Age must be positive")

p = Person(25)

print(p.get_age()) # 25

p.set_age(30)

print(p.get_age()) # 30
Using @property in Python (Pythonic Way)

Python provides a more elegant solution via the @property decorator, allowing access to
private variables as if they were public.

class Person:

def __init__(self, age):

self.__age = age

@property

def age(self):

return self.__age

@age.setter

def age(self, value):

if value > 0:

self.__age = value

else:

raise ValueError("Age must be positive")

p = Person(28)

print(p.age) # calls getter

p.age = 32 # calls setter

Advantages of @property Decorator

1. Cleaner, Pythonic syntax

2. Enables read-only, write-only, or read-write attributes

3. You can modify logic without changing external interface


Read-only Property Example

class Product:

def __init__(self, name):

self.__name = name

@property

def name(self):

return self.__name

p = Product("Laptop")

print(p.name) # Allowed

# p.name = "Tablet" # Error! No setter

Write-only Property Example

class SecretBox:

def __init__(self):

self.__secret = None

@property

def secret(self):

raise AttributeError("Not allowed to read secret")

@secret.setter

def secret(self, value):

self.__secret = value

box = SecretBox()
box.secret = "TopSecret" # Allowed

# print(box.secret) # Error

Best Practices with Getters and Setters

• Avoid unnecessary use unless control is required.

• Don’t overuse property decorators – use them when there's logic to protect/validate.

• Combine with private members to enforce encapsulation.

2.3 Name Mangling in Python

What is Name Mangling?

Name mangling is a mechanism in Python to make private variables harder to access from
outside the class by changing the name internally.

Python changes the name of private variables to _ClassName__variable.

Why Name Mangling?

• Prevent accidental overrides in subclasses.

• Protect data integrity.

Example of Name Mangling

class BankAccount:

def __init__(self, balance):

self.__balance = balance # private

def get_balance(self):

return self.__balance

a = BankAccount(1000)
# print(a.__balance) # AttributeError

print(a._BankAccount__balance) # 1000

Python doesn’t completely hide data — it uses this mechanism to discourage external
access.

Use Case: Avoiding Attribute Clashes in Inheritance

class Parent:

def __init__(self):

self.__data = 10

class Child(Parent):

def __init__(self):

super().__init__()

self.__data = 20

c = Child()

print(c._Parent__data) # 10

print(c._Child__data) # 20

Without mangling, both __data would point to the same variable — which is not what we
want in this case.

Encapsulation vs Abstraction

Encapsulation Abstraction

Hides internal state/data Hides implementation details

Done through access modifiers Done through abstract classes/interfaces

Achieved via class mechanisms Achieved via inheritance/polymorphism

You might also like