Applying SOLID Principles in Python: Examples and Best Practices

Single Responsibility Principle (SRP)

This principle states that each class should have a single responsibility. It emphasizes that a class should perform one specific function and not have too many reasons to change.

Example: Managing user information and sending email notifications.

class UserManager:
    def create_user(self, user_data):
        # Logic for creating a user
        pass

class EmailService:
    def send_email(self, email_data):
        # Logic for sending an email
        pass

Open/Closed Principle (OCP)

This principle encourages extending functionality by adding new code rather than modifying existing code.

Example: Handling different payment methods in an e-commerce application.

from abc import ABC, abstractmethod

class PaymentProcessor(ABC):
    @abstractmethod
    def process_payment(self):
        pass

class CreditCardPaymentProcessor(PaymentProcessor):
    def process_payment(self):
        # Logic for processing credit card payment
        pass

class PayPalPaymentProcessor(PaymentProcessor):
    def process_payment(self):
        # Logic for processing PayPal payment
        pass

Liskov Substitution Principle (LSP)

This principle asserts that objects of a derived class should be substitutable for objects of the base class without affecting the correctness of the program.

Example: Managing geometric shapes.

class Shape:
    def area(self):
        pass

class Rectangle(Shape):
    def area(self):
        return self.width * self.height

class Square(Shape):
    def area(self):
        return self.side * self.side

Interface Segregation Principle (ISP)

This principle advises breaking interfaces into smaller ones to avoid forcing classes to implement methods they don't need.

Example: Interfaces for updating and displaying data.

class UpdateableFeature:
    @abstractmethod
    def update_feature(self):
        pass

class DisplayableFeature:
    @abstractmethod
    def display_feature(self):
        pass

Dependency Inversion Principle (DIP)

This principle suggests using dependency injection to manage dependencies.

Example: Using dependency injection to manage dependencies.

class OrderProcessor:
    def __init__(self, db_connection, email_service):
        self.db_connection = db_connection
        self.email_service = email_service

Remember that applying SOLID principles in Python should be done flexibly based on the specific purpose of your project and your understanding of SOLID and Python.