π§ Python DeepCuts β π‘ Name Binding vs Assignment
Posted on: November 5, 2025
Description:
In Python, variables donβt βholdβ values like boxes β theyβre names bound to objects in memory.
Understanding this distinction helps you reason about how Python handles references, mutability, and side effects.
π§© Variables Are Just Names
When you assign a value to a variable, Python binds that name to an existing object β it doesnβt copy the data.
a = [1, 2, 3]
b = a
print("a is b:", a is b) # True β both names refer to the same list
Now both a and b point to the same list in memory.
π Rebinding vs Mutation
- Rebinding: assign a name to a new object
- Mutation: modify the contents of an existing object
a = [1, 2, 3]
b = a
a.append(4) # mutate β same object
print(a, b) # both change
a = [10, 20, 30] # rebind β a now points to a new list
print(a, b) # only a changes
This is why βpass-by-assignmentβ is a better way to describe how Python handles arguments.
π§© Immutable Objects Behave Differently
Integers, floats, strings, and tuples are immutable β any βchangeβ creates a new object.
x = 10
y = x
x += 5 # creates a new int object
print(x, y) # x: 15, y: 10
print(id(x), id(y)) # different IDs
Immutable objects canβt be modified in place, so every operation results in a new reference.
β‘ Mutability in Action: Lists vs Tuples
The += operator behaves differently for mutable and immutable types:
a = [1, 2]
b = a
a += [3, 4]
print(a is b) # True β list mutated in place
x = (1, 2)
y = x
x += (3, 4)
print(x is y) # False β new tuple created
Hereβs the key:
- list.iadd() mutates
- tuple.add() creates a new object
π§ Visualizing Name Binding
Think of names as arrows pointing to objects.
Multiple names can point to the same object β until one name is rebound.
data = {"key": [1, 2, 3]}
alias = data
alias["key"].append(4)
print(data, alias) # both changed
print(data is alias) # True
Both names reference the same dictionary, so mutation through one affects the other.
β Key Points
- β Assignment binds names β it doesnβt copy data.
- β Mutable objects change in place; immutable ones donβt.
- β is checks identity; == checks value.
- β Rebinding moves the label; mutation modifies the target.
- π§ Everything in Python is about names β objects β references.
Code Snippet:
import sys # to inspect object identity
a = [1, 2, 3] # create a list object
b = a # b is now another name pointing to the same list
print("a:", a)
print("b:", b)
print("a is b:", a is b) # True β same object
print("id(a):", id(a))
print("id(b):", id(b))
a = [1, 2, 3]
b = a # both refer to same list
print("Before mutation:", a, b)
a.append(4) # in-place mutation (list is mutable)
print("After mutation:", a, b) # both reflect the change
a = [10, 20, 30] # rebinding: a now points to a *new* list
print("After rebinding:", a, b) # b still refers to old list
x = 10
y = x # both names point to same int object
print("Before:", x, y)
print("id(x):", id(x))
print("id(y):", id(y))
x += 5 # new int created (since ints are immutable)
print("\nAfter x += 5:", x, y)
print("id(x):", id(x)) # different id β new object
print("id(y):", id(y)) # unchanged
# Mutable example
a = [1, 2]
b = a
a += [3, 4] # list.__iadd__ mutates in place
print("Lists β a is b:", a is b) # True
# Immutable example
x = (1, 2)
y = x
x += (3, 4) # tuple.__add__ creates a new object
print("Tuples β x is y:", x is y) # False
data = {"key": [1, 2, 3]}
alias = data
alias["key"].append(4)
print("Data:", data)
print("Alias:", alias)
print("Same object:", data is alias)
No comments yet. Be the first to comment!