How to Copy Class Instances in Python: Shallow vs Deep Copy

Use copy.copy and copy.deepcopy to clone class instances, showing how nested objects are shared or duplicated.

Easy Python 3.9+ Aug 9, 2026 OOP & classes 13 views 0 copies

Python code

22 lines
Python 3.9+
import copy


class Config:
    def __init__(self):
        self.settings = {"theme": "dark", "language": "en"}


if __name__ == "__main__":
    original = Config()

    shallow_copy = copy.copy(original)
    deep_copy = copy.deepcopy(original)

    shallow_copy.settings["theme"] = "light"
    deep_copy.settings["theme"] = "blue"

    print(f"Original theme: {original.settings['theme']}")
    print(f"Shallow copy theme: {shallow_copy.settings['theme']}")
    print(f"Deep copy theme: {deep_copy.settings['theme']}")
    print(f"Original and shallow share dict: {original.settings is shallow_copy.settings}")
    print(f"Original and deep share dict: {original.settings is deep_copy.settings}")

Output

stdout
Original theme: dark
Shallow copy theme: light
Deep copy theme: blue
Original and shallow share dict: True
Original and deep share dict: False

How it works

copy.copy creates a new instance but keeps references to the same nested objects, so the settings dict is shared between the original and the shallow copy. copy.deepcopy recursively duplicates all nested objects, giving the deep copy its own independent settings dict. That is why changing shallow_copy.settings['theme'] also changes original.settings, while deep_copy stays independent. This behavior matters whenever your class holds mutable attributes like lists, dicts, or other custom objects. Use copy.deepcopy when you need a fully independent clone, and copy.copy when you only need to duplicate the top-level object.

Common mistakes

  • Using the assignment operator `b = a` thinking it creates a copy—it only creates a new reference to the same object.
  • Forgetting that `copy.copy` is shallow and nested mutable attributes remain shared.
  • Assuming `copy.deepcopy` can copy everything—objects with locks or file handles may raise errors.

Variations

  1. Implement a `__copy__` or `__deepcopy__` method on your class to customize copy behavior.
  2. Use `copy.replace(instance, **changes)` (Python 3.13+) or `dataclasses.replace` for immutable dataclasses.

Real-world use cases

  • Cloning a configuration object before applying temporary overrides without mutating the global settings.
  • Duplicating a game state object for undo/redo operations where each snapshot must be fully independent.
  • Creating a backup of a data model object before batch updates, ensuring rollback logic works correctly.

Sponsored

Run this sample

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

Open editor

More from OOP & classes

Related tutorials and quizzes for this topic.