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