Terry Reedy a écrit : > "Christophe" <[EMAIL PROTECTED]> wrote in message > news:[EMAIL PROTECTED] > >>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 >>instead ? > > > 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 > this: > > 1. Write a specification for your an alternate, more complicated, iterator > protocol.
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 > specification. class ExaustedIteratorError(Exception): pass class safe_iter(object): def __init__(self, seq): self.it = iter(seq) def __iter__(self): return self def next(self): try: return self.it.next() except StopIteration: del self.it raise except AttributeError: raise ExaustedIteratorError > 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 ? print list(it) File "safe_iter_test.py", line 13, in next raise ExaustedIteratorError __main__.ExaustedIteratorError > 4. Consider how you would persuade people to add the extra machinery > needed. 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 > it. 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. -- http://mail.python.org/mailman/listinfo/python-list