restriction on sum: intentional bug?

Steven D'Aprano steven at REMOVE.THIS.cybersource.com.au
Tue Oct 27 17:12:38 EDT 2009


On Tue, 27 Oct 2009 05:29:46 -0700, Steve wrote:

> To me the current implementation is blatantly correct. sum is an
> operation on a list of numeric values, returning a numeric value - this
> is why we have the seemingly strange "".join() rather than [].join ("")

That is absolutely wrong. sum() works on anything with an __add__ method, 
including lists, tuples, and even strings provided you defeat the hand-
holding the function does:


>>> sum(["a", "b"], '')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: sum() can't sum strings [use ''.join(seq) instead]
>>>
>>> class Helper:
...     def __add__(self, other):
...             return other
...
>>> sum(["a", "b"], Helper())
'ab'



> I think duck typing is wonderful so long as its specific applications
> make sense. We don't handle integers being passed to len() do we?
> Technically we could return the number of digits but it wouldn't make
> sense as len() works on iterables.

The number of digits in what base?

len() works on anything with a __len__ method. Not all iterables have a 
known length. The most important examples are iterators and generators:


>>> len(iter('a'))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: object of type 'iterator' has no len()


And there's no guarantee that an object with __len__ is iterable:


>>> class Weird:
...     def __len__(self):
...             return 42
...
>>> len(Weird())
42
>>> list(Weird())
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: iteration over non-sequence


Admittedly it is an abuse of len() to create an non-iterable object with 
__len__, but you can do it.


Personally, I think that sum() should, at most, just emit a warning if 
you pass a string as the second argument. Anything more than that is 
needlessly nanny-like. Python let's you shoot yourself in the foot if you 
like, I don't see that the consequences of summing strings is so harmful 
that it needs to be exceptional. But apparently Guido disagrees, and so 
the behaviour will stay.



-- 
Steven



More information about the Python-list mailing list