Python Encapsulation

Introduction

Encapsulation is one of the fundamental concepts in object-oriented programming (OOP). It refers to the bundling of data (attributes) and methods (functions) that operate on the data into a single unit, or class. Encapsulation helps in restricting access to certain components of an object and can prevent the accidental modification of data.

Key Concepts

Public, Protected, and Private Members

  • Public Members: Accessible from outside the class. They are defined without any leading underscores.
  • Protected Members: Indicated by a single underscore (_). They are meant to be accessed within the class and its subclasses.
  • Private Members: Indicated by a double underscore (__). They are meant to be accessed only within the class.

Syntax

Defining a Class with Encapsulation

class MyClass: def __init__(self, public, protected, private): self.public = public # Public attribute self._protected = protected # Protected attribute self.__private = private # Private attribute def get_private(self): return self.__private def set_private(self, value): self.__private = value 

Example

Let’s consider a simple example of a Car class to demonstrate encapsulation.

Car Class

class Car: def __init__(self, brand, model, price): self.brand = brand # Public attribute self._model = model # Protected attribute self.__price = price # Private attribute def get_price(self): return self.__price def set_price(self, price): if price > 0: self.__price = price else: print("Invalid price") # Creating an object my_car = Car("Toyota", "Corolla", 20000) 

Explanation

  1. Public Attribute (brand): Accessible from outside the class directly.
  2. Protected Attribute (_model): Intended to be accessed within the class and its subclasses.
  3. Private Attribute (__price): Only accessible within the class using methods.

Using the Car Class

# Accessing public attribute print(my_car.brand) # Output: Toyota # Accessing protected attribute print(my_car._model) # Output: Corolla # Accessing private attribute using getter method print(my_car.get_price()) # Output: 20000 # Modifying private attribute using setter method my_car.set_price(25000) print(my_car.get_price()) # Output: 25000 # Trying to access private attribute directly (will raise an AttributeError) try: print(my_car.__price) except AttributeError as e: print(e) # Output: 'Car' object has no attribute '__price' 

Real-World Example: Bank Account

Let’s consider a real-world example of a bank account system.

BankAccount Class

class BankAccount: def __init__(self, account_number, balance): self.__account_number = account_number # Private attribute self.__balance = balance # Private attribute def get_balance(self): return self.__balance def deposit(self, amount): if amount > 0: self.__balance += amount return f"Deposited {amount}. New balance is {self.__balance}." else: return "Invalid amount" def withdraw(self, amount): if 0 < amount <= self.__balance: self.__balance -= amount return f"Withdrew {amount}. New balance is {self.__balance}." else: return "Invalid amount or insufficient balance" # Creating an object of the BankAccount class account = BankAccount("1234567890", 10000) 

Explanation

  1. Private Attributes (__account_number, __balance): These are only accessible within the class using methods.
  2. Public Methods (get_balance, deposit, withdraw): These methods provide controlled access to the private attributes.

Using the BankAccount Class

# Accessing and modifying balance using methods print(account.get_balance()) # Output: 10000 print(account.deposit(5000)) # Output: Deposited 5000. New balance is 15000. print(account.get_balance()) # Output: 15000 print(account.withdraw(3000)) # Output: Withdrew 3000. New balance is 12000. print(account.get_balance()) # Output: 12000 # Trying to access private attribute directly (will raise an AttributeError) try: print(account.__balance) except AttributeError as e: print(e) # Output: 'BankAccount' object has no attribute '__balance' 

Conclusion

Encapsulation in Python helps to protect the internal state of an object and prevents unauthorized access and modification. By using public, protected, and private attributes, you can control the access level of each attribute and method. This not only enhances the security of the code but also makes it more modular and maintainable. The real-world example of a bank account demonstrates how encapsulation can be applied to manage sensitive data effectively.

Leave a Comment

Scroll to Top