Skip to the content.
The Importance of Defensive Copying in Python | AI Systems Design From Scratch

Connect with Amin Boulouma Official

🏠 Documentation Hub 📝 Engineering Blog 💻 GitHub Repository

Defensive Copying: Protecting Your Internal State

Amin Boulouma, Software Engineer

In Python, collections like list, dict, and set are mutable objects. When you store these in a class and expose them via a getter method, returning the original reference is a common source of “spooky action at a distance”, where external code accidentally modifies your internal state.

The Problem: The “Reference Leak”

If your class returns the original reference to its internal list, any external caller can mutate that list, causing your object’s internal state to change without its knowledge.

The Leaky Pattern:

class DocumentManager:
    def __init__(self):
        self._documents = ["doc1.txt", "doc2.txt"]

    def get_documents(self):
        # DANGER: Returning a reference to the internal list
        return self._documents

# External code
manager = DocumentManager()
docs = manager.get_documents()
docs.append("malicious_doc.txt") # Modifies the internal state of 'manager'!

The Solution: Return a Copy

By returning self.documents.copy(), you return a shallow copy of the collection. The external caller now has its own version of the data, and any modifications it makes will not affect your class’s private state.

The Robust Pattern:

class DocumentManager:
    def __init__(self):
        self._documents = ["doc1.txt", "doc2.txt"]

    def get_documents(self):
        # SAFE: Returning a shallow copy
        return self._documents.copy()

# External code
manager = DocumentManager()
docs = manager.get_documents()
docs.append("safe_doc.txt") # manager._documents remains unchanged!

When to Copy vs. When to Encapsulate

Best Practices

Defensive copying is a simple technique that prevents subtle, hard-to-track bugs. By keeping your class’s internal state encapsulated, you create a system that is predictable, robust, and much easier to debug.

Connect with Amin Boulouma Official