On 21 February 2014 09:56, Peter Otten <__peter__@web.de> wrote:
אלעזר wrote:
What is the "classic" use case for next() raising StopIteration, to be silently caught ? We need __next__ to do so in for loops, but when do we need it in the functional form?
Pretty much every generator that treats the first item(s) specially, like the one I gave above:
But there are also cases where that implicit behaviour is not desired. I would rather have to explicitly return when that's what I want so that the control flow is very clear. For example when you use csv.DictReader and don't supply the fieldnames argument you are saying that you want to read a csv file with one header line containing column labels and zero or more data lines. To me a fully empty file (with no header line) is invalid but csv.DictReader will accept it as a csv file with zero rows. I would prefer an error in this case since it would only happen in my usage if an error had occurred somewhere else. One of the examples you linked to shows exactly my own practice of marking a next call with a comment: def __next__(self): while self.currkey == self.tgtkey: self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) self.tgtkey = self.currkey return (self.currkey, self._grouper(self.tgtkey)) def _grouper(self, tgtkey): while self.currkey == tgtkey: yield self.currvalue self.currvalue = next(self.it) # Exit on StopIteration self.currkey = self.keyfunc(self.currvalue) IMO if you want that behaviour then you should mark it to show that you thought about it and otherwise I'll treat any bare next with suspicion. Oscar