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?
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.
__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.
__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.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With