Design Patterns in Python - Interview Questions and Answers

Design patterns are proven solutions to recurring problems in software design. They provide a template for writing clean, maintainable, and reusable code.

They help reduce code complexity, improve maintainability, and promote code reuse and readability.

PEP 8 is the official style guide for writing readable Python code. It covers formatting, naming conventions, indentation, etc.

Follow PEP 8, use descriptive names, add comments/docstrings, avoid deep nesting, and split large functions.

Ensures only one instance of a class exists.

class Singleton:
    _instance = None
    def __new__(cls):
        if not cls._instance:
            cls._instance = super().__new__(cls)
        return cls._instance

Creates objects without exposing the instantiation logic.
Useful when object creation logic is complex.

An object (subject) notifies all its dependents (observers) when its state changes.

Enables selecting an algorithm at runtime.

Adds behavior to objects dynamically without altering the original class. Often implemented using @decorator syntax.

It allows incompatible interfaces to work together.

Composition uses "has-a" relationship, inheritance uses "is-a". Composition offers better flexibility.

If an object behaves like a duck (supports required methods), it's acceptable regardless of its class.

Encapsulates a request as an object, allowing parameterization of clients with queues, requests, etc.

Defines a skeleton method in the base class and allows subclasses to redefine parts.

A proxy controls access to the real object. Useful for lazy loading, access control, etc.

Separates object construction from representation, step-by-step.
Useful for creating complex objects.

Allows passing a request along a chain until handled.

By separating concerns and making code modular, testability improves naturally.

Model-View-Controller separates business logic, user interface, and control flow.

Model-View-Presenter. Similar to MVC but with better separation of presentation logic.

Patterns that deal with object creation: Singleton, Factory, Builder, Prototype.

Patterns that deal with class/object composition: Adapter, Bridge, Composite, Proxy.

Patterns that deal with communication between objects: Observer, Strategy, Command, etc.

Factory returns one product; Abstract Factory returns families of products.

 

A metaclass can enforce Singleton pattern at class creation level.

Captures and restores an object’s internal state without violating encapsulation.

Minimizes memory usage by sharing data with similar objects.

Separates an object’s abstraction from its implementation.

Both add functionality, but decorators do it dynamically and composition does it via object relationships.

They allow implementing many patterns (Strategy, Command, etc.) without needing complex class hierarchies.

Allows an object to change its behavior when its internal state changes.

Separate an algorithm from the object it operates on.
Useful for operations on object structures like ASTs.

Treat individual objects and compositions of objects uniformly.

Yes. They follow the Decorator Pattern by dynamically adding behavior.

Used via __iter__() and __next__() methods for custom iteration.

Strategy is chosen by the client; State changes internally.

Use locks from the threading module while instantiating.

A do-nothing object that avoids null checks.

class NullLogger:
    def log(self, msg): pass

PEP 20 (The Zen of Python) emphasizes readability, simplicity, and clarity.

Defines an object that centralizes complex communication between related objects.

Use function arguments or abstract base classes to generalize creation logic.

Python uses abc module for abstract classes. Interfaces aren’t native but can be mimicked.

For example, logging.getLogger() is a factory method.

MVC, Singleton (database connection), Template, etc.

Context Manager pattern.

Clones existing objects without depending on their classes.

Delays initialization until the value is needed.

Method chaining that improves code readability; often used in Builder.

It's a technique often supported by patterns like Factory, Singleton, or Service Locator.

When you need multiple instances for scalability or testing purposes.

Routing decorators (Decorator), Dependency injection, Template Method.

Yes, by improving modularity and readability, reducing quick-fix hacks.

It defines testing skeletons with specific override points.

Template uses inheritance, Strategy uses composition.

It delegates control of program flow to a framework or external code, supported by patterns.

 

Used for lazy loading (e.g., SQLAlchemy’s lazy relationships).

Assigns different behaviors dynamically at runtime by assigning roles.

Using static analysis tools or code reviews.

Yes, e.g., MVC uses Observer, Composite, and Strategy together.

A common but ineffective or counterproductive solution.

Separates persistence logic from business logic.

Repository encapsulates domain logic plus data access.

Tracks changes to entities and ensures a single commit.

They describe expected types and help tools like mypy.

Yes.

def singleton(cls):
    instances = {}
    def wrapper(*args, **kwargs):
        if cls not in instances:
            instances[cls] = cls(*args, **kwargs)
        return instances[cls]
    return wrapper

By chaining function calls conditionally.

 

Used mostly in C++, not directly applicable to Python.

Preserves metadata of the original function.

Each command stores state and has undo functionality.

Maintains a global list or dictionary of class/function instances.

Using Factory, Strategy, or Registry patterns.

Provides a simplified interface to a complex subsystem.

A pattern is a concept; a framework is a concrete implementation.

Encourages stricter interfaces and better readability.

Executes untrusted code in a controlled environment.

Used for UI components to react to data/model changes.

Reuses a fixed set of objects instead of creating/destroying them repeatedly.

A class with no methods but used for tagging. In Python, this can be done using mixins or annotations.

 

Each node can contain child nodes, making traversal and operations easier.

Classes providing optional, reusable functionality via multiple inheritance.

Django ORM (Unit of Work, Singleton), Flask (Decorator), SQLAlchemy (Proxy, Lazy loading).

 

Dependency injection or Observer patterns.

Instead of multiple constructors, use configuration functions.

Limits attribute creation, improves memory, but restricts flexibility.

Yes, using functools.wraps() with every decorator.

Enforces abstract methods, helpful in Template and Strategy patterns.

A unique placeholder object, e.g., object() or None.

Use __new__() or decorators to control instantiation.

Useful in State, Strategy, and Command pattern for predefined behavior sets.

Command pattern with stack support.

Yes, by returning self in setter methods.

Allows passing functions as arguments to be executed later.

It follows the Memoization pattern.

Makes instances callable like functions. Useful in factories and strategies.

Python’s dynamic nature reduces the need for some patterns (e.g., Factory, Strategy).

Used in language interpreters to define grammar and evaluate expressions.

 

Yes. Metaclasses can control instantiation at class creation.

Separates core functionality from plugins (modular systems).

 

Don’t overuse patterns, prefer Pythonic idioms, and ensure readability.

“You Ain’t Gonna Need It” — Avoid overengineering with unnecessary patterns.