In this tutorial, we will explore a foundational and powerful concept in Python programming: immutability, especially with respect to fundamental data types. This topic is essential for understanding how Python manages memory, variable assignment, and object behavior.
Fundamental Data Types
Before diving into immutability, let’s first recall the fundamental (primitive) data types in Python:
int
: Represents integers (e.g., 10, -5, 0)float
: Represents floating-point numbers (e.g., 3.14, -0.001)complex
: Represents complex numbers (e.g., 3 + 4j)bool
: Represents Boolean values (True or False)str
: Represents text (technically not always considered a primitive in other languages, but treated as fundamental in Python)
All of these types are immutable in Python.
What is Immutability?
In general terms:
- Mutable means changeable. You can alter the contents of the object.
- Immutable means not changeable. Once an object is created, its content cannot be altered.
In Python:
An immutable object is one whose value cannot be changed after it is created. If you try to change its value, Python creates a new object instead.
Immutability in Action: Understanding Through Examples
Let’s understand how immutability works with int
, one of Python’s fundamental data types.
Example 1: Single Variable Assignment and Update
x = 10 print("ID of x:", id(x)) x = x + 1 print("ID of x after increment:", id(x)) Output: ID of x: 140731423206104 ID of x after increment: 140731423206136
Explanation:
- Initially,
x
refers to the integer object10
. - When we do
x = x + 1
, Python does not update the existing object. Instead:- It creates a new object with the value
11
. - The variable
x
now refers to the new object. - The original object
10
is now unreferenced and becomes eligible for garbage collection.
- It creates a new object with the value
- You will see that the
id()
(which returns the memory address of an object) changes after reassignment.
Example 2: Two Variables Referencing the Same Object
x = 10 y = x print("ID of x:", id(x)) print("ID of y:", id(y)) y = y + 1 print("After incrementing y:") print("x =", x, "ID:", id(x)) print("y =", y, "ID:", id(y))
Explanation:
- Initially, both
x
andy
refer to the same object10
. - When we increment
y
, Python creates a new object with value11
. y
now refers to11
, whilex
continues to point to10
.
So:
- Two objects are now in memory: one with value
10
and another with value11
. - The IDs of
x
andy
are different after the update.
No object is garbage collected here because both 10
and 11
are still being referenced.
Key Takeaways
- All fundamental data types in Python are immutable.
This includesint
,float
,complex
,bool
, andstr
. - Once created, the value of an immutable object cannot be changed.
Instead, any “modification” results in the creation of a new object. - Memory addresses (IDs) help prove immutability.
You can use theid()
function to see whether a new object is created. - Garbage Collection
If an object is no longer referenced by any variable, Python’s garbage collector will clean it up.
Why is Immutability Required in Python?
Python uses immutability to support efficient memory usage and performance through object reusability.
Example: Reusing Integer Objects
a = 10 b = 10 c = 10 print(id(a), id(b), id(c)) Output: 140731113351896 140731113351896 140731113351896
- Although these assignments appear on separate lines, Python does not create three separate objects.
- Python checks if an object with the required value already exists.
- If it does, Python reuses that object.
This means a
, b
, and c
all point to the same object in memory.
Why is this beneficial?
- Memory Efficiency: Instead of creating multiple copies of the same value, one object is shared across multiple variables.
- Performance Improvement: Creating an object is expensive. By reusing objects, Python avoids repeated creation, which boosts performance.
Standard vs Non-Standard Behavior
When testing object identity (is
) with Python interactive tools like IDLE or console, you might notice some unexpected behavior:
a = 1000 b = 1000 print(a is b) # May return False in some REPLs
This happens because:
- Python often reuses integers in the range
[-5, 256]
. - Outside this range, behavior depends on the implementation (standard interpreter vs REPL).
To avoid confusion:
- Use standard environments like PyCharm, VSCode, or standalone scripts.
- Do not rely on REPLs (IDLE, console) for verifying object reuse behavior.
What is REPL?
REPL stands for:
- Read
- Eval
- Loop
These tools are meant for quick testing, not full-scale development.
Example: List Modification
l = [10, 20, 30] print("Before modification:", l, "ID:", id(l)) l[0] = 7777 print("After modification:", l, "ID:", id(l)) Output: Before modification: [10, 20, 30] ID: 2265743036736 After modification: [7777, 20, 30] ID: 2265743036736