Ojasa Mirai

Ojasa Mirai

Python

Loading...

Learning Level

🟢 Beginner🔵 Advanced
Classes & ObjectsMethods & SelfInstance VariablesClass VariablesConstructors & InitializationInheritance BasicsPolymorphismEncapsulationMagic Methods & Dunder
Python/Oop/Constructors Initialization

🔨 Constructors & Initialization — Advanced Patterns and Context Managers

Advanced initialization patterns include the builder pattern for complex object creation, lazy initialization for performance, and context managers for resource management. These patterns solve real-world problems in large applications.


🎯 Builder Pattern

The builder pattern constructs complex objects step by step, making code readable and flexible.

class SQLQuery:
    def __init__(self):
        self.select_clause = []
        self.from_clause = None
        self.where_clause = []
        self.order_by = None
        self.limit_value = None

class QueryBuilder:
    def __init__(self):
        self.query = SQLQuery()

    def select(self, *columns):
        self.query.select_clause = list(columns)
        return self

    def from_table(self, table):
        self.query.from_clause = table
        return self

    def where(self, condition):
        self.query.where_clause.append(condition)
        return self

    def order_by(self, column, direction='ASC'):
        self.query.order_by = f"{column} {direction}"
        return self

    def limit(self, count):
        self.query.limit_value = count
        return self

    def build(self):
        sql = f"SELECT {', '.join(self.query.select_clause)}"
        if self.query.from_clause:
            sql += f" FROM {self.query.from_clause}"
        for where in self.query.where_clause:
            sql += f" WHERE {where}"
        if self.query.order_by:
            sql += f" ORDER BY {self.query.order_by}"
        if self.query.limit_value:
            sql += f" LIMIT {self.query.limit_value}"
        return sql

# Fluent interface
query = (QueryBuilder()
    .select("name", "email", "age")
    .from_table("users")
    .where("age > 18")
    .where("status = 'active'")
    .order_by("name")
    .limit(10)
    .build())

print(query)

⏰ Lazy Initialization

Defer expensive initialization until actually needed, improving startup performance.

class LazyProperty:
    def __init__(self, func):
        self.func = func
        self.name = func.__name__

    def __get__(self, obj, objtype=None):
        if obj is None:
            return self
        value = self.func(obj)
        setattr(obj, self.name, value)
        return value

class DataAnalyzer:
    def __init__(self, filename):
        self.filename = filename

    @LazyProperty
    def data(self):
        print(f"Loading {self.filename}...")
        # Expensive operation
        return [1, 2, 3, 4, 5]

    @LazyProperty
    def statistics(self):
        print("Computing statistics...")
        return {"mean": sum(self.data) / len(self.data)}

analyzer = DataAnalyzer("data.txt")
print("Analyzer created")  # No loading yet

print(analyzer.data)       # Triggers loading
print(analyzer.data)       # Already loaded, no re-computation
print(analyzer.statistics) # Compute statistics

🔄 Context Managers

Context managers handle resource initialization and cleanup using `__enter__` and `__exit__`.

class FileManager:
    def __init__(self, filename, mode='r'):
        self.filename = filename
        self.mode = mode
        self.file = None

    def __enter__(self):
        print(f"Opening {self.filename}")
        self.file = open(self.filename, self.mode)
        return self.file

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(f"Closing {self.filename}")
        if self.file:
            self.file.close()
        return False  # Don't suppress exceptions

# Use with 'with' statement
with FileManager("test.txt", "w") as f:
    f.write("Hello, World!")
# File is automatically closed

# Can also use contextlib
from contextlib import contextmanager

@contextmanager
def temp_file(filename):
    print(f"Creating {filename}")
    f = open(filename, "w")
    try:
        yield f
    finally:
        f.close()
        print(f"Cleaned up {filename}")

with temp_file("temp.txt") as f:
    f.write("temporary content")

📚 Real-World Examples

Database Connection Pool

class DatabasePool:
    def __init__(self, host, port, max_connections=5):
        self.host = host
        self.port = port
        self.max_connections = max_connections
        self.available = []
        self.in_use = set()

    def _create_connection(self):
        return f"Connection to {self.host}:{self.port}"

    def get_connection(self):
        if self.available:
            conn = self.available.pop()
        else:
            if len(self.in_use) < self.max_connections:
                conn = self._create_connection()
            else:
                raise RuntimeError("No connections available")
        self.in_use.add(conn)
        return conn

    def release_connection(self, conn):
        self.in_use.discard(conn)
        self.available.append(conn)

class DatabaseTransaction:
    def __init__(self, pool):
        self.pool = pool
        self.connection = None

    def __enter__(self):
        self.connection = self.pool.get_connection()
        print(f"Transaction started: {self.connection}")
        return self.connection

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.pool.release_connection(self.connection)
        print(f"Transaction ended: {self.connection}")
        return False

pool = DatabasePool("localhost", 5432, max_connections=3)

with DatabaseTransaction(pool) as conn:
    print(f"Using: {conn}")

Request/Response Handler

class RequestHandler:
    def __init__(self, timeout=30):
        self.timeout = timeout
        self.request = None
        self.response = None

    def __enter__(self):
        self.request = {"method": "GET", "url": "/api/data"}
        print(f"Processing request: {self.request}")
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        self.response = {"status": 200, "data": []}
        print(f"Response: {self.response}")
        if exc_type:
            print(f"Error occurred: {exc_val}")
            self.response["status"] = 500
        return False

with RequestHandler(timeout=5) as handler:
    print("Executing request logic")
    handler.response = {"status": 200, "data": [1, 2, 3]}

✅ Key Takeaways

ConceptRemember
Builder PatternConstruct complex objects step by step
Fluent InterfaceMethods return self for chaining
Lazy InitializationDefer expensive operations until needed
Context ManagerUse __enter__ and __exit__ for resources
with StatementAutomatic cleanup of resources
LazyPropertyDescriptor for lazy-loaded attributes
Resource ManagementEnsure cleanup even with exceptions
ReadabilityPatterns make code more maintainable

🔗 What's Next?

Continue with advanced inheritance patterns.

Advanced: Inheritance Basics →


Ready to practice? Try challenges or explore more concepts


Resources

Python Docs

Ojasa Mirai

Master AI-powered development skills through structured learning, real projects, and verified credentials. Whether you're upskilling your team or launching your career, we deliver the skills companies actually need.

Learn Deep • Build Real • Verify Skills • Launch Forward

Courses

PythonFastapiReactJSCloud

© 2026 Ojasa Mirai. All rights reserved.

TwitterGitHubLinkedIn