
On Thu, Jan 2, 2014 at 1:37 PM, James Powell <james@dontusethiscode.com> wrote:
On 01/02/2014 06:24 PM, Guido van Rossum wrote:
The current behavior is intentional, and the ambiguity of strings themselves being iterables is the main reason. Since startswith() is almost always called with a literal or tuple of literals anyway, I see little need to extend the semantics. (I notice that you don't actually give any examples where the iterator would be useful -- have you encountered any, or are you just arguing for consistency's sake?)
This is driven by a real-world example wherein a large number of prefixes stored in a set, necessitating:
any('spam'.startswith(c) for c in prefixes) # or 'spam'.startswith(tuple(prefixes))
Neither of these strikes me as bad. Also, depending on whether the set of prefixes itself changes dynamically, it may be best to lift the tuple() call out of the startswith() call. Note that for performance, I suspect that the any() version will be slower if you can avoid calling tuple() every time -- I recall once finding that x.startswith('ab') benchmarked slower than x[:2] == 'ab' because the name lookup for 'startswith' dominated the overall time.
However, .startswith doesn't seem to be the only example of this, and the other examples are free of the string/iterable ambiguity:
isinstance(x, {int, float})
But this is even less likely to have a dynamically generated argument. And there could still be another ambiguity here: a metaclass could conceivably make its instances (i.e. classes) iterable.
I do agree that it's definitely important to retain the behaviour of:
'spam'.startswith('sz')
Duh. :-)
At same time, I think the non-string iterable problem is already fairly well-known and not a source of great confusion. How often has one typed:
isinstance(x, Iterable) and not isinstance(x, str)
If you find yourself typing that a lot I think you have a bigger problem though. All in all I hope you will give up your push for this feature. It just doesn't seem all that important, and you really just move the inconsistency to a different place (special-casing strings instead of tuples). -- --Guido van Rossum (python.org/~guido)