Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
Difference between Shallow and Deep Copy of a Class
A class is a blueprint that defines objects' attributes (data) and behaviors (methods). When working with class instances, you often need to create copies. Python provides two types of copying: shallow copy and deep copy, each with different behaviors regarding nested objects.
Shallow Copy
Shallow copy creates a new object but stores references to the original elements. Instead of duplicating nested objects, it copies their references. This means modifications to nested objects affect both the original and the copy.
Shallow copy is performed using copy.copy() method from the copy module.
Deep Copy
Deep copy creates a new object with copies of all nested elements. It recursively duplicates all objects, creating completely independent instances. Changes to nested objects don't affect the original.
Deep copy is achieved using copy.deepcopy() method from the copy module.
Memory Address Example
This example demonstrates how shallow and deep copies handle memory addresses differently ?
import copy
class MyClass:
def __init__(self, name, numbers):
self.name = name
self.numbers = numbers
def __repr__(self):
return f"MyClass(name='{self.name}', numbers={self.numbers})"
# Creating an instance
original_obj = MyClass("Alice", [10, 20, 30])
print("Original object memory addresses:")
print("name:", id(original_obj.name))
print("numbers:", id(original_obj.numbers))
# Making copies
shallow_copy = copy.copy(original_obj)
deep_copy = copy.deepcopy(original_obj)
print("\nShallow copy memory addresses:")
print("name:", id(shallow_copy.name))
print("numbers:", id(shallow_copy.numbers))
print("\nDeep copy memory addresses:")
print("name:", id(deep_copy.name))
print("numbers:", id(deep_copy.numbers))
Original object memory addresses: name: 140234567890432 numbers: 140234567891584 Shallow copy memory addresses: name: 140234567890432 numbers: 140234567891584 Deep copy memory addresses: name: 140234567890432 numbers: 140234567892736
Notice that shallow copy shares the same memory addresses for nested objects, while deep copy creates new memory locations for mutable objects like lists.
Behavior Demonstration
This example shows how modifications affect original and copied objects ?
import copy
class ClassEx:
def __init__(self, name):
self.name = name
self.items = []
def add_item(self, item):
self.items.append(item)
def __str__(self):
return f"{self.name}: {self.items}"
# Create original instance
original = ClassEx("Original")
original.add_item("Item 1")
original.add_item("Item 2")
# Create copies
shallow_copy = copy.copy(original)
deep_copy = copy.deepcopy(original)
print("After creating copies:")
print("Original:", original)
print("Shallow:", shallow_copy)
print("Deep:", deep_copy)
# Modify each object
original.add_item("From Original")
shallow_copy.add_item("From Shallow")
deep_copy.add_item("From Deep")
print("\nAfter modifications:")
print("Original:", original)
print("Shallow:", shallow_copy)
print("Deep:", deep_copy)
After creating copies: Original: Original: ['Item 1', 'Item 2'] Shallow: Original: ['Item 1', 'Item 2'] Deep: Original: ['Item 1', 'Item 2'] After modifications: Original: Original: ['Item 1', 'Item 2', 'From Original', 'From Shallow'] Shallow: Original: ['Item 1', 'Item 2', 'From Original', 'From Shallow'] Deep: Original: ['Item 1', 'Item 2', 'From Deep']
Key Differences
| Aspect | Shallow Copy | Deep Copy |
|---|---|---|
| Memory Sharing | Shares references to nested objects | Creates independent copies |
| Performance | Faster, uses less memory | Slower, uses more memory |
| Modifications | Changes affect original object | Changes don't affect original |
| Use Case | When sharing references is acceptable | When complete independence is needed |
Conclusion
Use shallow copy when you need a new object but can share references to nested objects. Use deep copy when you need complete independence between the original and copied objects, especially with mutable nested data.
