Search code examples
pythonadditionmagic-methods

Different return types, overloading __add__


I wish to implement something like the following. There is a class foo which contains a list of infoo objects. I was thinking that in order to overload the __add__ operator I should

class foo(object):
    def __init__(self, infoo_list):
        self.args = infoo_list

    def __add__(self, other):
        if isinstance(other, type(self)):
            newargs = self.args + other.args
            return foo(newargs)
        elif isinstance(other, infoo_type):
            newargs = self.args + [other]
            return foo(newargs)


class infoo (object):
    def __init__(self):
        pass

    def __add__(self, other):
        return foo([self, other])


infoo_type = type(infoo())

As you may see foo is a container of infoo objects. You may have an infoo object alone in the universe and operate on it. But, no matter what, if you have to manage more than one, the foo object comes into play.

Even though the user could instantiate an infoo object to play, the code is oriented towards letting the interface of foo handle whenever there are more than one infoo.

Is this good practice? Am I breaking some golden rule?


Solution

  • Essentially covered in the comments, but something like this would be a cleaner design:

    class InFoo:
        pass
    
    class Foo:
        def __init__(self, infoos):
            self.args = list(infoos)
    
        def __add__(self, other):
            if isinstance(other, __class__):
                oargs = other.args
            elif isinstance(other, InFoo):
                oargs = [other]
            return foo(self.args + oargs)
    

    There does not appear to be any good reason to define __add__ on InFoo, since addition is only meaningful for containers in this case. This also eliminates the need to externally define infoo_type. Python convention is to make class names CamelCase and pretty much everything else snake_case.