Module 1: Runtime Model and the Data Model

References, Mutability, and Copying

References, Mutability, and Copying

Advanced Python design begins with a precise reference model. Assignment binds names, function calls share object references, shallow copies duplicate only an outer container, and deep copies recursively traverse an object graph.

Module: Module 1: Runtime Model and the Data Model

Core mental model

This lesson is built around four connected ideas. Read them as a decision framework, then prove each one with the walkthrough.

  • Rebinding changes a name; mutation changes an object visible through every alias.
  • A shallow copy shares nested objects with its source.
  • Deep copy is expensive and can copy more identity than the domain permits.
  • Object lifetime follows reachability, while resources still require explicit cleanup.

Walkthrough

from copy import copy, deepcopy

original = [{"tags": ["python"]}]
shallow = copy(original)
deep = deepcopy(original)

shallow[0]["tags"].append("runtime")
deep[0]["tags"].append("isolated")

print(original)
print(shallow)
print(deep)

original and shallow contain the same nested dictionary and list, so the first append is shared. deep owns recursively copied nested containers. In real models, database handles, locks, caches, and identities often make blind deepcopy inappropriate.

Hands-on lab

Create an object graph with shared nested data. Draw identities before and after assignment, shallow copy, selective manual copy, and deep copy. Implement the narrowest copy operation your domain actually needs.

What to watch for

  • copying an outer list does not isolate its elements.
  • deepcopy can duplicate objects that should remain shared or noncopyable.
  • Mutable defaults and repeated nested-list multiplication introduce hidden aliases.

Engineering checklist

  • Connect the lesson's mental model to the choices made in the walkthrough.
  • Test the normal case, an empty or boundary case, and one invalid case.
  • Keep external input, side effects, and reusable logic in clearly separated layers.
  • Prefer the clearest correct implementation before optimizing or generalizing it.

Completion check

You can implement the lab without copying the example, explain the core concepts in your own words, and show tests or terminal output that demonstrate the expected and failure paths.