As I understand it, for it to be possible to cast sum()
on an object, it must be an iterable, and must be "addable", i.e. it must implement methods __iter__
and __add__
. However, when I do this for my class Point
(just an example), this doesn't work.
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
def __add__(self, other):
return Point(self.x + other.x, self.y + other.y)
def __iter__(self):
return self
def __str__(self):
return str((self.x, self.y))
print(Point(2, 2) + Point(1, 1))
>>> (3, 3) # As expected; good!
points = [Point(0, 0), Point(2, 0), Point(0, 2), Point(2, 2)]
print(sum(points)) # Expect (4, 4)
>>> TypeError: unsupported operand type(s) for +: 'int' and 'Point'
If I implement __radd__
the same as __add__
I then get an attribute error when I try sum()
:
AttributeError: 'int' object has no attribute 'x'
Based on the errors my Points
are somewhere being separated to just ints
but I'm not sure where.
Thanks for any help.
This happens because sum
starts with a default value of int
and when doing sum(points)
what really is happening is sum
is first trying to add 0 + Point(0, 0)
and hence the error. If you check the help on sum
, this will become pretty evident,
Help on built-in function sum in module builtins:
sum(iterable, start=0, /) Return the sum of a 'start' value (default: 0) plus an iterable of numbers
When the iterable is empty, return the start value. This function is intended specifically for use with numeric values and may reject non-numeric types.
Change the line from,
>>> print(sum(points))
to
>>> print(sum(points, Point(0, 0)))