It is in most of the situations easy to implement copy constructors (or overloaded assignment operator) in C++ since there is a concept of pointers. However, I'm quite confused about how to implement shallow and deep copy in Python.
I know that there are special commands in one of the libraries but they don't work on classes that you have written by yourself. So what are the common ways to implement?
P.S. Showing process on some basic data structures (linked list or tree) will be appreciated.
EDIT: Thanks, they worked, it was my mistake in syntax.
I am very interested in overwriting these functions with __copy__()
and __deep_copy()__
. For example. how can I make a deep copy without knowing which type of information is in a data structure?
The python copy
module can reuse the pickle
module interface for letting classes customize copy behaviour.
The default for instances of custom classes is to create a new, empty class, swap out the __class__
attribute, then for shallow copies, just update the __dict__
on the copy with the values from the original. A deep copy recurses over the __dict__
instead.
Otherwise, you specify a __getstate__()
method to return internal state. This can be any structure that your class __setstate__()
can accept again.
You can also specify the __copy__()
and/or __deepcopy__()
methods to control just copy behaviour. These methods are expected to do all the copying themselves, the __deepcopy__()
method is passed a memo mapping to pass on to recursive deepcopy()
calls.
An example could be:
from copy import deepcopy
class Foo(object):
def __init__(self, bar):
self.bar = bar
self.spam = expression + that * generates - ham # calculated
def __copy__(self):
# self.spam is to be ignored, it is calculated anew for the copy
# create a new copy of ourselves *reusing* self.bar
return type(self)(self.bar)
def __deepcopy__(self, memo):
# self.spam is to be ignored, it is calculated anew for the copy
# create a new copy of ourselves with a deep copy of self.bar
# pass on the memo mapping to recursive calls to copy.deepcopy
return type(self)(deepcopy(self.bar, memo))
This example defines custom copy hooks to prevent self.spam
being copied too, as a new instance will calculate it anew.