How to Implement the Prototype Pattern with Deep Copy in Python

Implements the Prototype design pattern using copy.deepcopy to clone complex objects without sharing mutable state.

Easy Python 3.9+ Aug 9, 2026 System design patterns 13 views 0 copies

Python code

27 lines
Python 3.9+
import copy
from dataclasses import dataclass, field
from typing import List

@dataclass
class Engine:
    horsepower: int

@dataclass
class Car:
    brand: str
    engine: Engine
    accessories: List[str] = field(default_factory=list)

def clone_prototype(car: Car) -> Car:
    return copy.deepcopy(car)

if __name__ == "__main__":
    original = Car("Tesla", Engine(450), ["Autopilot", "Sunroof"])
    cloned = clone_prototype(original)

    # Mutate the clone only
    cloned.engine.horsepower = 500
    cloned.accessories.append("Heated seats")

    print("Original:", original)
    print("Cloned  :", cloned)

Output

stdout
Original: Car(brand='Tesla', engine=Engine(horsepower=450), accessories=['Autopilot', 'Sunroof'])
Cloned  : Car(brand='Tesla', engine=Engine(horsepower=500), accessories=['Autopilot', 'Sunroof', 'Heated seats'])

How it works

The Prototype pattern lets you create new objects by copying an existing template rather than rebuilding from scratch. copy.deepcopy recursively duplicates all nested objects, so the cloned Engine gets its own memory space. Mutating the clone's nested attributes never leaks back to the original. Dataclasses with field(default_factory=list) give each instance a fresh mutable list, avoiding shared reference bugs.

Common mistakes

  • Using `copy.copy` instead of `copy.deepcopy` — the clone shares nested mutable objects with the original.
  • Adding a mutable default like `accessories=[]` directly in the dataclass, which is shared across all instances.
  • Forgetting to return the deep copy when wrapping the pattern in a factory function.

Variations

  1. Use `copy.deepcopy(obj)` directly instead of a wrapper function when you only have one clone site.
  2. Implement a `clone()` method on the class that internally calls `copy.deepcopy(self)` for a more OOP-oriented interface.

Real-world use cases

  • Cloning configuration objects before applying environment-specific overrides in a CI/CD system.
  • Duplicating UI component state trees in a frontend data layer to support undo/redo features.
  • Instantiating new parser contexts from a base context without mutating the shared template used by other workers.

Sponsored

Run this sample

Open the browser IDE to tweak the example and see results without installing anything.

Open editor

More from System design patterns

Related tutorials and quizzes for this topic.