Reputation: 1345
In "How to override the copy/deepcopy operations for a Python object?" post, it is written in one of the answers that:
def __deepcopy__(self, memo):
cls = self.__class__
result = cls.__new__(cls)
memo[id(self)] = result
for k, v in self.__dict__.items():
setattr(result, k, deepcopy(v, memo))
return result
Is a possible way of overriding the deepcopy method. I do not understand what each of the lines does. What is the purpose of this implementation? Can't I just create my own copy method with something specific for my class like the following?
def my_copy(self, original_obj):
obj = MyClass()
obj.a = (copy of a from the other object)
obj.b = (copy of b from the other object)
...
return obj
Upvotes: 2
Views: 2435
Reputation: 3355
You are right you could to this in the way you presented. However this would be specific to your object implementation. The example you posted is much more generic and could handle copying many different classes of objects. It could also be made as a mixin to easy add it to your class.
The code presented, do this by:
def __deepcopy__(self, memo):
cls = self.__class__ # Extract the class of the object
result = cls.__new__(cls) # Create a new instance of the object based on extracted class
memo[id(self)] = result
for k, v in self.__dict__.items():
setattr(result, k, deepcopy(v, memo)) # Copy over attributes by copying directly or in case of complex objects like lists for exaample calling the `__deepcopy()__` method defined by them. Thus recursively copying the whole tree of objects.
return result
Note also that if your class consisted of complex attributes like lists you would also need to call directly deepcopy on them or otherwise you would end up with a shallow copy for some of the attributes.
EDIT
memo
is a dict, where id-to-object correspondence is kept to reconstruct complex object graphs perfectly.
Upvotes: 3