[Python-ideas] __iter__ implies __contains__?
Masklinn
masklinn at masklinn.net
Sun Oct 2 13:28:53 CEST 2011
On 2011-10-02, at 03:14 , Steven D'Aprano wrote:
> These changes don't sound even close to reasonable to me. It seems to me that the OP is making a distinction that doesn't exist.
>
> If you can write this:
>
> x = collection[0]; do_something_with(x)
> x = collection[1]; do_something_with(x)
> x = collection[2]; do_something_with(x)
> # ... etc.
>
> then you can write it in a loop by hand:
>
> i = -1
> try:
> while True:
> i += 1
> x = collection[i]
> do_something_with(x)
> except IndexError:
> pass
>
> But that's just a for-loop in disguise. The for-loop protocol goes all the way back to Python 1.5 and surely even older. You should, and can, be able to write this:
>
> for x in collection:
> do_something_with(x)
>
> Requiring collection to explicitly inherit from a Sequence ABC breaks duck typing and is anti-Pythonic.
>
> I can't comprehend a use-case where manually extracting collection[i] for sequential values of i should succeed
You can write this:
x = collection['foo']; do_something_with(x)
x = collection['bar']; do_something_with(x)
x = collection['baz']; do_something_with(x)
you can't write either of the other two options, but since Python calls the exact same method, if you somehow do a containment check (or an iteration) of a simple k:v collection instead of getting a clear exception about a missing `__iter__` or `__contains__` you get a not-very-informative `KeyError: 0` 3 or 4 levels down the stack, and now have to hunt how in hell's name somebody managed to call `collection[0]`.
More information about the Python-ideas
mailing list