Python NumPy: How to Make a NumPy Array Read-Only in Python
When working with NumPy arrays, there are situations where you need to protect your data from accidental modification. For example, you might have a configuration array, a reference dataset, or shared constants that should remain unchanged throughout your program's execution. Making a NumPy array read-only (immutable) ensures that any attempt to modify it raises an error immediately, helping you catch bugs early.
In this guide, you'll learn how to make a NumPy array immutable, how to reverse it, and best practices for working with read-only arrays.
How Read-Only Arrays Work in NumPy
Every NumPy array has an internal set of flags that control its behavior. One of these flags is writeable, which determines whether the array's data can be modified. By setting this flag to False, the array becomes read-only - any attempt to change its values will raise a ValueError.
You can inspect an array's flags at any time:
import numpy as np
a = np.array([1, 2, 3, 4, 5])
print(a.flags)
Output:
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
WRITEBACKIFCOPY : False
Notice that WRITEABLE is True by default, meaning the array can be modified.
Making an Array Read-Only with flags.writeable
The most direct way to make a NumPy array immutable is by setting the writeable flag to False:
import numpy as np
a = np.array([10, 20, 30, 40, 50])
# Make the array read-only
a.flags.writeable = False
print(f"Writeable: {a.flags.writeable}")
print(a)
Output:
Writeable: False
[10 20 30 40 50]
Now, if you try to modify any element, NumPy raises an error:
a[0] = 99
Output:
ValueError: assignment destination is read-only
Using setflags() Method
An alternative approach is the setflags() method, which provides the same functionality with a slightly different syntax:
import numpy as np
a = np.array([1, 2, 3, 4, 5])
# Make read-only using setflags
a.setflags(write=False)
print(f"Writeable: {a.flags.writeable}")
Output:
Writeable: False
Both a.flags.writeable = False and a.setflags(write=False) produce identical results. Choose whichever you find more readable.
Full Example: Before and After Making an Array Read-Only
This example demonstrates the complete lifecycle - creating an array, modifying it, making it read-only, and then attempting another modification:
import numpy as np
a = np.zeros(5)
print("Original array:")
print(a)
# Modify the array (works fine)
a[1] = 42
print("\nAfter modification:")
print(a)
# Make the array read-only
a.setflags(write=False)
print("\nArray is now read-only.")
# Attempt to modify again (raises an error)
try:
a[1] = 100
except ValueError as e:
print(f"Error: {e}")
Output:
Original array:
[0. 0. 0. 0. 0.]
After modification:
[ 0. 42. 0. 0. 0.]
Array is now read-only.
Error: assignment destination is read-only
Wrapping modification attempts in a try/except block is a good practice when working with arrays that might be read-only, especially in shared codebases or library code.
Making an Array Writeable Again
If you need to restore write access to a read-only array, simply set the flag back to True:
import numpy as np
a = np.array([1, 2, 3])
a.flags.writeable = False
# Restore write access
a.flags.writeable = True
a[0] = 99
print(a)
Output:
[99 2 3]
You cannot make an array writeable again if it does not own its data. For example, arrays created from memory-mapped files or certain slices may refuse to become writeable. In such cases, you'll need to create a copy with a.copy().
Common Mistake: Assuming Slices Are Independent
A common pitfall is assuming that a slice of a read-only array creates an independent, writeable copy. In reality, slices share the same underlying data, so they inherit the read-only flag:
import numpy as np
a = np.array([10, 20, 30, 40, 50])
a.flags.writeable = False
# ❌ Slice inherits read-only status
b = a[1:4]
try:
b[0] = 999
except ValueError as e:
print(f"Error: {e}")
Output:
Error: assignment destination is read-only
To get a writeable copy of the data, use the copy() method explicitly:
# ✅ Create an independent writeable copy
b = a[1:4].copy()
b[0] = 999
print(b)
Output:
[999 30 40]
Practical Use Cases
Making arrays read-only is useful in several real-world scenarios:
- Shared constants: Prevent accidental modification of global configuration arrays or lookup tables used across multiple modules.
- Data integrity: Protect raw input data from being altered during preprocessing, ensuring you can always trace back to the original values.
- Debugging: Catch unintended writes early by making arrays immutable as soon as they are initialized.
- Multithreaded applications: Mark arrays as read-only when sharing data between threads to avoid race conditions.
Summary
| Method | Syntax | Effect |
|---|---|---|
flags.writeable | a.flags.writeable = False | Directly sets the writeable flag |
setflags() | a.setflags(write=False) | Sets the flag via a method call |
| Restore write access | a.flags.writeable = True | Makes the array modifiable again |
| Writeable copy | a.copy() | Creates an independent, writeable copy |
Making a NumPy array read-only is a simple but powerful technique for protecting your data.
Set writeable to False once your array is initialized, and NumPy will enforce immutability by raising a ValueError on any modification attempt.
When you need a modifiable version, use copy() to create an independent array without affecting the original.