我一直在通过搜索教程来学习Python 2。我发现了关于 class 的事情。我在__add__
dunder-method中遇到了一些麻烦。我不知道如何添加类的2个对象。
更清楚:
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)
我知道这不是添加2个对象的最佳方法吗?
答案 0 :(得分:4)
您可以将map
与operator.add
一起使用,并在*
中使用__add__
进行迭代解包。例如:
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))
它确实会返回“预期对象”:
>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7)
>>> obj1 + obj2
Add_obj(6, 12)
然而,map
并不是真正需要的,它只是一种非常高效且简短的方法来实现这一目标。您也可以使用理解和zip
代替:
def __add__(self, other):
return self.__class__(*[num1+num2 for num1, num2 in zip(self.num, other.num)])
正如评论中指出的那样,这也有效,但当两个Add_obj
具有不同的长度时,可能会产生意外(甚至错误)的结果。如果要禁止添加两个不同大小的对象,则可以引发异常:
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
例如:
>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7, 2)
>>> obj1 + obj2
ValueError: cannot two Add_obj with different lengths
或者你可以填补较短的一个:
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)])
例如:
>>> obj1 = Add_obj(2, 5)
>>> obj2 = Add_obj(4, 7, 2)
>>> obj1 + obj2
Add_obj(6, 12, 2)
答案 1 :(得分:1)
使用zip
是一个好主意。
class Add_obj:
def __init__(self, *num):
self.num = num
def __repr__(self):
return 'Add_obj{}'.format(self.num)
def __add__(self, other):
return Add_obj(*(sum(pair) for pair in zip(self.num, other.num)))
obj1 = Add_obj(2, 5)
obj2 = Add_obj(4, 7)
obj3 = obj1 + obj2
print(obj1)
print(obj2)
print(obj3)