0

I have some question about good practice. So say we have some class which we want to use as iterator. It class should returns first some header and then returns its blocks. I see two ways for this case:

  1. The first one is "classic". Return in iter methods self and put some logic in next method, like:
def __next(self): if not self._header_was_returned: self._header_was_returned = True return self._header if self._index >= self._count_blocks: raise StopIteration block = self._blocks[self._index] self._index += 1 return block 
  1. Or another one, in this case used less code, just implenet iter method:
def __iter__(self): yeild self._header for block in self._blocks: yield block 

Another case is create some class IteratorForMyBlockClass and implements ``_next``` method there, but it similar for the first case.

Updated:

From "Fluent Python" (Chapter 14). Main class is itarable (but not iterator). Main class should return some IteratorClass in __iter__ method. And in Iterator class I should put some logic:

class MainClass: def __init__(self, header, blocks): self._header = header self._blocks = blocks def __iter__(self): return MainClassIterator(self._header, self._blocks) class MainClassIterator: def __init__(self, header, blocks): self._header = header self._blocks = blocks self._index = 0 self._header_was_returned = False def __iter__(self): return self def __next__(self): if not self._header_was_returned: self._header_was_returned = True return self._header if self._index >= len(self._blocks): raise StopIteration block = self._blocks[self._index] self._index += 1 return block 

Is that a good solution?

5
  • Please do not return self in __iter__ if that iterator is stateful (nearly all iterators are). If you would use multiple iterators concurrently, things will go wrong. Commented Jul 21, 2019 at 18:44
  • 3
    You seem to be mixing up the concepts of "iterator" and "iterable". Are you aware there is a difference, and are you sure you want these objects to be iterators rather than iterable? Commented Jul 21, 2019 at 18:45
  • So...should implement own Iterator class which will be returned in iter method? And put in Iterator class next method like in the first case? Commented Jul 21, 2019 at 18:46
  • I updated my question, please check it Commented Jul 21, 2019 at 19:00
  • in the second case where you only implement __iter__, you are not implementing an iterator, you are implementing an iterable. Commented Jul 21, 2019 at 19:06

1 Answer 1

3

You don't really need a MainClassIterator. Since a generator function always returns an iterator, an easy solution would be to put this __iter__ in MainClass:

def __iter__(self): yield self._header yield from self._blocks 
Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.