๐Ÿ” Python OOP โ€” Encapsulation

Introduction ๐ŸŒŸ

**Encapsulation** is one of the core principles of Object-Oriented Programming (OOP). It refers to **binding data and methods together** and **controlling access** to that data. Encapsulation helps protect internal object data from accidental modification.

Note

๐Ÿ’ก Encapsulation = Data Protection + Controlled Access
Python achieves this using private, protected attributes and getter/setter methods.

1. Why Encapsulation? ๐Ÿค”

  • โœ” Prevents direct modification of internal data
  • โœ” Adds security and control
  • โœ” Allows validation before updating values
  • โœ” Organizes code for maintainability

2. Protected Attributes (_single underscore) ๐Ÿ›ก๏ธ

A single underscore (_attribute) indicates that the attribute is **protected** and should not be accessed directly outside the class.

protected_attribute.py

class Person:
    def __init__(self, name):
        self._name = name   # protected attribute

p = Person("Sathish")
print(p._name)  # technically allowed but discouraged

Note

โœ” This is only a convention โ€” it warns developers not to modify it directly.

3. Private Attributes (__double underscore) ๐Ÿ”’

Double underscore (__attribute) makes the attribute **private**, meaning it is not accessible directly from outside the class.

private_attribute.py

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance   # private

acc = BankAccount(1000)
print(acc.__balance)  # โŒ AttributeError

โœ” Python performs name mangling:__balance becomes _BankAccount__balance internally.

4. Accessing Private Attributes Using Getters & Setters ๐Ÿ”ง

getter_setter_encapsulation.py

class BankAccount:
    def __init__(self, balance):
        self.__balance = balance

    def get_balance(self):          # getter
        return self.__balance

    def set_balance(self, amount):  # setter
        if amount < 0:
            raise ValueError("Invalid amount")
        self.__balance = amount

acc = BankAccount(500)
print(acc.get_balance())
acc.set_balance(800)
print(acc.get_balance())

โœ” Allows data validation and safe access

5. Encapsulation Using @property Decorators ๐ŸŽ€

property_encapsulation.py

class Employee:
    def __init__(self, salary):
        self._salary = salary

    @property
    def salary(self):
        return self._salary

    @salary.setter
    def salary(self, value):
        if value < 0:
            raise ValueError("Salary cannot be negative")
        self._salary = value

e = Employee(30000)
e.salary = 35000
print(e.salary)

Note

โœ” @property is the Pythonic way to implement encapsulation.

6. Encapsulation Example โ€” Student Marks System ๐Ÿงฎ

student_marks.py

class Student:
    def __init__(self, marks):
        self.__marks = marks

    @property
    def marks(self):
        return self.__marks

    @marks.setter
    def marks(self, value):
        if not (0 <= value <= 100):
            raise ValueError("Marks must be between 0 and 100")
        self.__marks = value

s = Student(85)
s.marks = 95
print(s.marks)

โœ” Fully encapsulated with validation.

7. Encapsulation Example โ€” Online Shopping Cart ๐Ÿ›’

cart_example.py

class Cart:
    def __init__(self):
        self.__items = []   # private list

    @property
    def items(self):
        return self.__items

    def add_item(self, product):
        self.__items.append(product)

c = Cart()
c.add_item("Laptop")
c.add_item("Mouse")
print(c.items)

โœ” Items list cannot be modified directly
โœ” All changes go through controlled methods

8. Encapsulation with Private Methods ๐Ÿ”

private_method.py

class Demo:
    def __private_method(self):
        print("This is private")

    def public_method(self):
        self.__private_method()

d = Demo()
d.public_method()

โœ” Private methods are used internally to restrict logic.

9. Name Mangling in Python ๐Ÿงฉ

name_mangling.py

class Test:
    def __init__(self):
        self.__value = 10

t = Test()
print(t._Test__value)  # Accessing private attribute using name mangling

Note

โ— Should NOT be used in real applications โ€” used only for debugging or learning.

10. Encapsulation vs Abstraction โš”๏ธ

EncapsulationAbstraction
Protects data using private/protected membersHides complexity from the user
Focuses on โ€œHow to protect?โ€Focuses on โ€œWhat to show?โ€
Achieved using getters, setters, @propertyAchieved using abstract classes/methods

11. Best Practices ๐Ÿ’ก

  • โœ” Use _attribute for protected data
  • โœ” Use __attribute for private data
  • โœ” Prefer @property for encapsulation
  • โœ” Avoid unnecessary private attributes
  • โœ” Use methods to safely modify sensitive data

Conclusion ๐ŸŽ‰

>>โ€œEncapsulation protects the heart of your objects โ€” ensuring data remains safe and controlled.โ€ โœจ

You now fully understand Encapsulation in Python! Want the next topic? Try Inheritance, Polymorphism, Magic Methods, or OOP Exercises. Just tell me! ๐Ÿ˜Š