Search code examples
pythonmagic-methods

Copy.deepcopy vs creating new instances in magic methods


When over-riding python add, mul etc magic methods, it seems to be normal to create a new instance of the class and then return that. For example:

class test_class_simple:
    def __init__(self, x):
        self.x = x

    def __add__(self, other):
        return test_class(self.x + other.x)

However, another option is to have the add method copy the existing instance and then just change its value:

import copy
def __add__(self, other):
    new = copy.deepcopy(self)
    new.x = self.x + other.x
    return new

When working with complex classes with lots of variables, it seems easier and probably also safer to deepcopy them (as per example 2) and then to change the particular attribute that the magic method affects. However I don't see many examples of people doing this, and so I'm wondering if there's some drawback to it further down the line that I'm unaware of. Is there any harm to this approach?

Thanks!


Solution

  • I would go with your first way of overriding __add__. A couple reasons why:

    • copy.deepcopy() is written in Python, not C, so you probably aren't going to get any performance gains from doing this
    • Using copy.deepcopy() isn't as clear as just instantiating a new object, because the object returned by the __add__ doesn't have any direct relationship with the current object
    • If the object you're instantiating has some kind of self-referential cycle, copy.deepcopy() might get stuck, as it uses recursion to do the deep copy.