Re: __next__ and StopIteration

2015-02-10 Thread Ethan Furman
On 02/10/2015 08:53 AM, Ian Kelly wrote: > On Tue, Feb 10, 2015 at 9:44 AM, Ethan Furman wrote: >> On 02/09/2015 08:46 PM, Chris Angelico wrote: >>> >>> class Grid: >>> blah blah >>> >>> def __iter__(self): >>> for row in range(self._rows): >>> for col in range(self._co

Re: __next__ and StopIteration

2015-02-10 Thread Chris Kaynor
On Tue, Feb 10, 2015 at 12:30 AM, Ian Kelly wrote: > > On Mon, Feb 9, 2015 at 5:59 PM, Chris Kaynor wrote: > > On Mon, Feb 9, 2015 at 4:42 PM, Steven D'Aprano > > wrote: > >> so that's an excellent sign that doing so is best practice, but it should > >> not be seen as *required*. After all, perh

Re: __next__ and StopIteration

2015-02-10 Thread Ian Kelly
On Tue, Feb 10, 2015 at 9:44 AM, Ethan Furman wrote: > On 02/09/2015 08:46 PM, Chris Angelico wrote: >> >> class Grid: >> blah blah >> >> def __iter__(self): >> for row in range(self._rows): >> for col in range(self._cols): >> if self._grid[row][col]: >>

Re: __next__ and StopIteration

2015-02-10 Thread Ethan Furman
On 02/09/2015 08:46 PM, Chris Angelico wrote: > > class Grid: > blah blah > > def __iter__(self): > for row in range(self._rows): > for col in range(self._cols): > if self._grid[row][col]: > yield self._grid[row][col] I strongly sug

Re: __next__ and StopIteration

2015-02-10 Thread Ian Kelly
On Mon, Feb 9, 2015 at 5:59 PM, Chris Kaynor wrote: > On Mon, Feb 9, 2015 at 4:42 PM, Steven D'Aprano > wrote: >> so that's an excellent sign that doing so is best practice, but it should >> not be seen as *required*. After all, perhaps you have good reason for >> wanting your iterable class to o

Re: __next__ and StopIteration

2015-02-09 Thread Chris Angelico
On Tue, Feb 10, 2015 at 5:16 PM, Charles Hixson wrote: > Yes, rows and cols are lists, but I'm going to need to iterate through them > more than once. I'd rather do without a included class, but if a properly > formed iterator can only be cycled through once, and if I understand > properly that m

Re: __next__ and StopIteration

2015-02-09 Thread Charles Hixson
On 02/09/2015 08:46 PM, Chris Angelico wrote: On Tue, Feb 10, 2015 at 3:33 PM, Charles Hixson wrote: The proper version of the "hard way" is: 1) The __iter__ method of the iterable constructs a new iterator instance and returns it. 2) The __iter__ method of the *iterator* simply returns itse

Re: __next__ and StopIteration

2015-02-09 Thread Steven D'Aprano
Chris Kaynor wrote: > On Mon, Feb 9, 2015 at 4:42 PM, Steven D'Aprano > wrote: >> so that's an excellent sign that doing so is best practice, but it should >> not be seen as *required*. After all, perhaps you have good reason for >> wanting your iterable class to only be iterated over once. > >

Re: __next__ and StopIteration

2015-02-09 Thread Chris Angelico
On Tue, Feb 10, 2015 at 3:33 PM, Charles Hixson wrote: >> The proper version of the "hard way" is: >> >> 1) The __iter__ method of the iterable constructs a new iterator >> instance and returns it. >> >> 2) The __iter__ method of the *iterator* simply returns itself. >> >> 3) The __next__ method o

Re: __next__ and StopIteration

2015-02-09 Thread Charles Hixson
On 02/09/2015 03:56 PM, Ian Kelly wrote: On Mon, Feb 9, 2015 at 4:30 PM, Steven D'Aprano wrote: The way you write iterators is like this: Method 1 (the hard way): - Give your class an __iter__ method which simply returns self: def __iter__(self): return self - Give your clas

Re: __next__ and StopIteration

2015-02-09 Thread Chris Angelico
On Tue, Feb 10, 2015 at 12:11 PM, Steven D'Aprano wrote: >> Yes, it is allowed. But when you write code that's documented as being >> "broken", you should expect annoying, subtle errors, maybe a long way >> down the track. > > Well, that depends, don't it? > > Am I really going to care if the iter

Re: __next__ and StopIteration

2015-02-09 Thread Ned Batchelder
On 2/9/15 2:24 PM, Ned Batchelder wrote: On 2/9/15 2:14 PM, Charles Hixson wrote: I'm trying to write a correct iteration over a doubly indexed container, and what I've got so far is:def __next__ (self): for rowinrange(self._rows): for col in range(self._cols):

Re: __next__ and StopIteration

2015-02-09 Thread Steven D'Aprano
Chris Angelico wrote: > On Tue, Feb 10, 2015 at 11:42 AM, Steven D'Aprano > wrote: >> Also, *technically* iterators may be re-iterable. The docs say that >> iterators which fail to raise StopIteration forever once they are >> exhausted are "broken", but the docs do not forbid broken iterators. >>

Re: __next__ and StopIteration

2015-02-09 Thread Chris Kaynor
On Mon, Feb 9, 2015 at 4:42 PM, Steven D'Aprano wrote: > so that's an excellent sign that doing so is best practice, but it should > not be seen as *required*. After all, perhaps you have good reason for > wanting your iterable class to only be iterated over once. In fact, there is one in the std

Re: __next__ and StopIteration

2015-02-09 Thread Chris Angelico
On Tue, Feb 10, 2015 at 11:42 AM, Steven D'Aprano wrote: > Also, *technically* iterators may be re-iterable. The docs say that > iterators which fail to raise StopIteration forever once they are exhausted > are "broken", but the docs do not forbid broken iterators. Consenting > adults and all that

Re: __next__ and StopIteration

2015-02-09 Thread Steven D'Aprano
Ian Kelly wrote: > On Mon, Feb 9, 2015 at 4:30 PM, Steven D'Aprano > wrote: [...] >> Your class is itself an iterator. > > This is an anti-pattern, so don't even suggest it. Iterables should > never be their own iterators. Otherwise, your iterable can only be > iterated over once! Hmmm, good po

Re: __next__ and StopIteration

2015-02-09 Thread Ian Kelly
On Mon, Feb 9, 2015 at 4:30 PM, Steven D'Aprano wrote: > The way you write iterators is like this: > > > Method 1 (the hard way): > > - Give your class an __iter__ method which simply returns self: > > def __iter__(self): > return self > > - Give your class a __next__ method (`next` in

Re: __next__ and StopIteration

2015-02-09 Thread Steven D'Aprano
Charles Hixson wrote: > I'm trying to write a correct iteration over a doubly indexed container, > and what I've got so far is:def __next__ (self): > for rowinrange(self._rows): > for col in range(self._cols): > if self._grid[row][col]: >

Re: __next__ and StopIteration

2015-02-09 Thread Rob Gaddi
On Mon, 09 Feb 2015 11:14:55 -0800, Charles Hixson wrote: > I'm trying to write a correct iteration over a doubly indexed container, > and what I've got so far is:def __next__ (self): > for rowinrange(self._rows): > for col in range(self._cols): >

Re: __next__ and StopIteration

2015-02-09 Thread Ned Batchelder
On 2/9/15 2:14 PM, Charles Hixson wrote: I'm trying to write a correct iteration over a doubly indexed container, and what I've got so far is:def __next__ (self): for rowinrange(self._rows): for col in range(self._cols): if self._grid[row][col]:

__next__ and StopIteration

2015-02-09 Thread Charles Hixson
I'm trying to write a correct iteration over a doubly indexed container, and what I've got so far is:def __next__ (self): for rowinrange(self._rows): for col in range(self._cols): if self._grid[row][col]: yieldself._grid[row]