Shallow copy and deep copy are two ways of copying objects in Python.
A shallow copy only copies the references to the elements making up the original object. When we perform an operations from either the copy or the original object, if the operation changes a shared element, the change is reflected on the other object.
On the other hand, a deep copy makes a duplicate of the elements making up the original object, which takes up a different memory locations , so any changes on either object are not reflected on the other.
Assignment vs Copy
You should not confuse between copy and assignment operations. Copying means creating a new object with the exact same content as an existing object, while assignment involves linking a name to the object, so that it can be accessed by that name. When copying, you create two separate objects with same values, while with assignment, you get a single object referenced by two(or more) names.
In the above example a
and b
literally refers to the same object and thus there is no copy operation going on.
The copy
module in the standard library provide tools necessary for shallow copying as well as deep copying.
shallow copies
Shallow copies stores references to the elements making up the original object, rather than replicating them. You should note that you will have two separate objects only that they share commons elements.
The copy()
function in the copy
module is used to perform shallow copies.
As shown in the above example, when we perform a shallow copy, we get two separate objects but that are made of same elements. Thus, if we change an element that makes up both, the effect will be reflected on both objects. This means that even if we change the objects through the copy, the effect will be seen on the original object.
Deep copies
When we perform a deep copy operation, a new objects is created with duplicate elements of the original object. This duplicate elements are allocated separate memory locations, meaning that any operation on either the original or the copy will not be reflected on the other.
We use the deepcopy()
function to create deep copies.
Customizing copy behaviour in custom objects
The __copy__()
and the __deepcopy__ ()
dunder methods can be used to customize how the interpreter handles copying the contents of objects.
The __copy__()
method is called without any argument and should return the shallow copy of the object.
The __deepcopy__()
dunder method should return the deep copy of the object. We can override this method to customize how deep copy operation is carried on the objects of the class.