Search code examples
pythonclassmethodsiteratorgenerator

How to create reusable generator classes in Python?


I need to create generator which can be use more than one time. I have classes like this:

class iter_maker:
    def __iter__(self):
        return self

class next_maker():
    def __next__(self,):
        self.count+=1
        if self.count > self.limit:
            raise StopIteration
        return self.count ** 2

class sq(iter_maker, next_maker):
    def __init__(self, limit):
        self.count = 0
        self.limit = limit

So, when I create an instance:

w = sq(10)

and:

print(list(w))
print(list(w))

I got:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[]

But I Wanted:

[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
[1, 4, 9, 16, 25, 36, 49, 64, 81, 100]

I think __iter__ method must return new object each time I use this, but I don't know how to do that.

Thanks!


Solution

  • It depends on how you want to use it. If just as outlined above (or similar) then this should work:

    class sq:
        
        def __init__(self, limit):
            self.limit = limit
        
        def __iter__(self):
            yield from (n**2 for n in range(1, self.limit + 1))
    

    This

    w = sq(10)
    print(list(w))
    print(list(w))
    

    gives you

    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]
    [1, 4, 9, 16, 25, 36, 49, 64, 81, 100]