0

I am designing a custom iterator in python:

class Iterator():

    def __init__(self):

        return 

    def fit(self, n):
        self.n = n
        return self

    def __iter__(self):
        for i in range(self.n):
            yield i

        return 




it = Iterator().fit(10)

for i in it:
    print(i)

it.fit(20)
for i in it:
    print(i)

It is working fine but I am wondering if it is possible that a new fit is called before that the previous one is finished leading to strange behaviour of the class.

If yes how should I design it to make it more robust? It is important to have some parameters passed from the fit method.

EDIT: I will introduce an example that is similar to my original problem

The iterator class is designed to be used by a User class. It is important that when the evaluate method is called all the numbers until n/k are printed. Without any exception.

Maybe the use of a iterator.fit(n) method solves the problem? class Iterator():

    def __init__(self, k):
        self.k = k
        return 

    def fit(self, n):

        for i in range(int(n/self.k)):
            yield i
        return 



class User():

    def __init__(self, iterator):

        self.iterator = iterator
        return

    def evaluate(self, n):

        for i in self.iterator.fit(n):
            print(i)

        return



it = Iterator(2)
u = User(it)

u.evaluate(10) # I want to be sure that all the numbers until 9 are printed
u.evaluate(20)  # I want to be sure that all the numbers until 20 are printed
Donbeo
  • 17,067
  • 37
  • 114
  • 188
  • You look like you're trying to write co-routines. See [this question](http://stackoverflow.com/questions/19302530/python-generator-send-function-purpose). – Peter Wood Jul 12 '15 at 12:02

2 Answers2

1

Because each call to range creates a new iterator, there will be no conflicts if you make multiple calls to fit.

Your class is a bit weird. You could either remove the __init__, as it does nothing, or put the fit method in there.

it = Iterator()
it1 = iter(it.fit(10))
it2= iter(it.fit(5))
print it1.next()
print it1.next()
print it2.next()
print it1.next()
>>0
  1
  0
  2
Gecko
  • 1,379
  • 11
  • 14
  • but is it possible to iterater for example only on the first 5 values after the first `fit` call and then call `fit` again?? – Donbeo Jul 12 '15 at 11:56
  • Yes. In fact, using the `iter` function it is easy to test. I added an example. – Gecko Jul 12 '15 at 12:02
  • I would like to avoid this. I want to be sure that if the iteration starts it is completed before a new `fit` is called. Is there any way to do that? – Donbeo Jul 12 '15 at 12:04
  • You would need to give an example. What output would you expect to happen in the example I give above. More specifically, if fit is called again with a different number, what impact does that have? – Gecko Jul 12 '15 at 12:12
0

You haven't actually written an iterator -- you've written a normal class that can return an iterator. The iterator that you are returning is a generator.

What this means is that calling fit() during iteration will have no effect -- at least, not until you iterate over your object again. For example:

>>> it = Iterator()
>>> for x in it.fit(7):
...   it.fit(3)
...   print(x)
... 
0
1
2
3
4
5
6
>>> for x in it:
...   print(x)
... 
0
1
2
Community
  • 1
  • 1
Ethan Furman
  • 63,992
  • 20
  • 159
  • 237