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

Reply via email to