Question about exausted iterators
chris.cavalaria at free.fr
Fri May 19 05:01:01 EDT 2006
Terry Reedy a écrit :
> "Christophe" <chris.cavalaria at free.fr> wrote in message
> news:446c2dea$0$5306$626a54ce at news.free.fr...
>>Instead of saying that all works as intended could you be a little
>>helpful and tell me why it was intended in such an obviously broken way
> I answered both your explicit and implied questions in good faith. But you
> seem to be too attached to your pre-judgment to have benefited much, so I
> won't waste my time and yours saying more. Instead I suggest that you try
> 1. Write a specification for your an alternate, more complicated, iterator
Specification : same as now except iterators raise once StopIteration
and any subsequent call to next raises ExaustedIteratorError.
> 2. Write a simple class with .next method that implements your
def __init__(self, seq):
self.it = iter(seq)
> 3. Test your class with your example.
>>> it = safe_iter(range(10))
>>> print list(it)
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> print list(it)
Traceback (most recent call last):
File "safe_iter_test.py", line 20, in ?
File "safe_iter_test.py", line 13, in next
> 4. Consider how you would persuade people to add the extra machinery
Well, the main reason for such change is and will always be to catch
bugs. The fact is, using duct typing is something very common with the
Python language. And as such, considering a lot of functions which take
sequences as parameters work as well with an iterator instead, you can
say that it's an application of duct typing.
The problem is of course the same as for cases. Even if those two objets
( iterator and container ) look alike from a certain point of view, they
have some fundamental differences.
So, we have quite a few functions which take freely either a container
or an iterator, until someone changes that function a little. At that
point there are three kind errors which happen :
- the function expected a sequence and tries to access it's  operator
which fails. Standard duct typing behaviour.
- the function uses the iterator more than once and so, sometimes it
works without errors but produces an incorrect result.
- the function uses the iterator more than once but never exhausts it's
values. Same result as above but much harder to catch.
In the sake of avoiding behaviour which lets obvious errors pass and
produces incorrect results, I propose to change the standard behaviour
of all the iterators in the standard Python. The change will be so that
they refuse to be used anymore once they have been exausted. Thus it'll
help catch the second class. The other procedure used to catch such bugs
would require explicit typing of the function parameters but this is for
some other proposal.
> 5. Consider what you would do when people don't.
I'm already doing it. Cleaning up the code, changing parameters names
around so that it is clear such parameter is an iterator and that other
one is not, making some functions explicitly refuse iterators etc ... It
should not that that last feature will be useful even without the
exhausted iterator guard I propose.
> If you want, post a report on your experiment, and I will read it if I see
I suppose I could add safe_iter to the builtins in my project and use it
around. It would be easy to catch all usages of that one once we settle
on something different then.
More information about the Python-list