On 02/09/2015 03:56 PM, Ian Kelly wrote:
On Mon, Feb 9, 2015 at 4:30 PM, Steven D'Aprano
<steve+comp.lang.pyt...@pearwood.info> 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 Python 2) which *returns* a
value. You will need to track which value to return yourself. It must raise
StopIteration when there are no more values to return. Don't use yield.
def __next__(self):
value = self.value
if value is None:
raise StopIteration
self.value = self.calculate_the_next_value()
return value
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!
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 of the iterator tracks the current value and
returns the next value. Note that the iterator should never store the
iterable's data internally, unless the iterable is immutable and the
calculation is trivial (e.g. a range object). Instead, it should
determine the next value by referring to its source iterable.
So if I'm understanding this correctly, I should implement as an
internal class within Grid something like:
class GridIter(Iterator):
""" A class to iterate over the cells of a Grid instance
Vars:
row :: The row currently being iterated over.
col :: Yhe column currently being iterated over.
grid :: The grid instance being iterated over.
"""
def __init__ (self, grid):
"""
Params:
grid :: The instance of the grid to iterate over.
"""
self.row = -1
self.col = -1
self.grid = grid
#end __init__
def __iter__ (self):
return self
def __next__ (self):
if self.row == -1 and self.col == -1:
self.row = 0
self.col = 0
elif self.col >= grid.cols():
self.row = self.row + 1
self.col = 0
if self.row > grid.rows():
raise StopIteration
if not [row, col] in self.grid:
return self.__next__()
return grid(row, col)
--
https://mail.python.org/mailman/listinfo/python-list