1

This question was asked many times, but I didn't see an answer for my version directly, so...

With iterator protocol, like example below I could make objects that behave like iterators and also like generators.

  1. Is there real distinction between an iterator and a generator on object level?
  2. Is yield keyword just a sugar to python interpreter to create class with iterator protocol?
  3. Could I replace every generator (or co-routine) function with a class that supports iterator protocol?

Examples:

def make_iterable():
    return [1, 2, 3, 4, 5]

# This class behaves like a function above when iterating its instances.
class IteratorBehave(object):
    def __init__(self):
        self.data = [1, 2, 3, 4, 5]
    def __iter__(self):
        class Iter(object):
            def __init__(self, data):
                self.index = 0
                self.data = data
            def next():
                if self.index < len(self.data):
                    current = self.data[self.index]
                    self.index += 1
                    return current
                raise StopIteration()

        return Iter(self.data)

def make_generator():
    v = 1
    while v <= 5:
        yield v
        v += 1  

# This class behaves like a generator function above when iterating its instances.
class GeneratorBehave(object):
    def __init__(self):
        self.max = 5
    def __iter__(self):
        class Gen(object):
            def __init__(self, max):
                self.current = 1
                self.max = max
            def next():
                if self.current <= self.max:
                    current = self.current
                    self.current += 1
                    return current
                raise StopIteration()
        return Gen(self.max)
Pavel Patrin
  • 1,630
  • 1
  • 19
  • 33
  • http://stackoverflow.com/questions/2776829/difference-between-pythons-generators-and-iterators – sshashank124 Apr 21 '15 at 22:31
  • It is not same my question. – Pavel Patrin Apr 21 '15 at 22:34
  • can you make your classes a bit more readable?? I have no idea what you're trying to show. In short though, yes and yes (see above link and assuming I understood you correctly) – Matthew Apr 21 '15 at 22:34
  • @PavelPatrin: It's the same question. If the top answer isn't enough for you, scroll down; the other answers might help. – user2357112 Apr 21 '15 at 22:41
  • @PavelPatrin Not all generators (especially when being used as coroutines) can be replaced an iterator. Generators support using the `send` method to inject values into a running function, and the `throw` method to inject an exception. Neither of these are part of the iterator protocol, but are essential parts of implementing coroutines with generators. See [PEP 342](https://www.python.org/dev/peps/pep-0342/) for more info. – dano Apr 21 '15 at 22:45
  • @dano I mean that: Every time I could abandon _yield_ keyword and write a class, that behave identically to a co-routine. Correct? – Pavel Patrin Apr 21 '15 at 22:49
  • 1
    @PavelPatrin You could always write code that looks completely different but is functionally equivalent, yes. Event loop-based Coroutines can be replaced by a series of functions with callbacks, for example. It's just much less convenient and readable. For regular coroutines that you use directly with `send`/`throw`, you could probably get the same functionality using a series of `Queue` objects, but again, its much less convenient/readable. – dano Apr 21 '15 at 23:00

0 Answers0