Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

__add__ two class objects

I've been learning Python 2 by searching for tutorials. I'm discovering things about class. I have some trouble in __add__ dunder-method. I don't know how to add 2 objects of a class.

To be clearer:

class Add_obj:
    def __init__(self, *num):
        self.num = num

    def __repr__(self):
        return 'Add_obj{}'.format(self.num)

    def __add__(self, other):
        for i in zip(*(self.num + other.num)):
            # and then some codes over here

#when:
obj1 = Add_obj(2, 5)
obj2 = Add_obj(4, 7)
# it should return Add_obj(6, 12)

I know it's not the best way to add 2 objects?

like image 350
Ted.Magnito Avatar asked Sep 25 '17 14:09

Ted.Magnito


People also ask

How do you add two class objects in Python?

In other words, to add two objects together in Python, the class implementing the objects needs to implement the __add__() method. Another related method is the __radd__() method. This flips a+b with b+a.

What does __ add __ do in Python?

__add__ magic method is used to add the attributes of the class instance. For example, let's say object1 is an instance of a class A and object2 is an instance of class B and both of these classes have an attribute called 'a', that holds an integer.

What is __ class __ in Python?

__class__ # Output: <class 'type'> Thus, the above code shows that the Human class and every other class in Python are objects of the class type . This type is a class and is different from the type function that returns the type of object.

What is __ methods in Python?

The __call__ method enables Python programmers to write classes where the instances behave like functions. Both functions and the instances of such classes are called callables.


1 Answers

You could use map with operator.add and iterable unpacking (using *) in __add__. For example:

import operator

class Add_obj:
    def __init__(self, *num):
        self.num = num

    def __repr__(self):
        return 'Add_obj{}'.format(self.num)

    def __add__(self, other):
        return self.__class__(*map(operator.add, self.num, other.num))

And it indeed returns the "expected object":

>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7)
>>> obj1 + obj2
Add_obj(6, 12)

However map is not really required it's just a very performant and short way to accomplish this. You could also use a comprehension and zip instead:

def __add__(self, other):
    return self.__class__(*[num1+num2 for num1, num2 in zip(self.num, other.num)])

As pointed out in the comments this will also work, but possibly give unexpected (or even wrong) results when the two Add_obj have different lengths. If you want to prohibit adding two different sized objects you could raise an Exception instead:

def __add__(self, other):
    if len(self.num) != len(other.num):
        raise ValueError('cannot two Add_obj with different lengths')
    ...  # use one of the both approaches from above

For example:

>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7, 2)
>>> obj1 + obj2
ValueError: cannot two Add_obj with different lengths

Or you could zero-pad the shorter one:

from itertools import izip_longest as zip_longest  # only zip_longest on Python 3

class Add_obj:

    ...

    def __add__(self, other):
        return self.__class__(*[num1+num2 for num1, num2 in zip_longest(self.num, other.num, fillvalue=0)])

For example:

>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7, 2)
>>> obj1 + obj2
Add_obj(6, 12, 2)
like image 178
MSeifert Avatar answered Sep 22 '22 21:09

MSeifert