[Python-ideas] iterable: next() and __iter__() -- and __reset()

spir denis.spir at gmail.com
Thu Mar 4 11:35:53 CET 2010


Hello,

(1) I do not understand an iterable type's __iter__() method to be compulsary. Actually, each time I have defined one, I had to write:
    def __iter__(self):
        return self
So, I guess that if python does not find __iter__(), but the object defines next(), then by default the said object could be used as its own iterator. This is what I understand by "iterable" and next() is the required method for it.
Or even better: only if the object does not define next(), then python falls back to looking for __iter__(). Is there any obstacle for this I cannot see?
Side-question: In which cases is it necessary to define the iterator as a separate object?

(2) But: for any reason next() is not spelled as a "magic" method. If this method becomes the distinctive method of iterables, then it should be called __next__() for consistency.
Side-question: Why is it called next(), as it is a magic method for iterators already?

(3) What I miss actually for iterables (which are their own iterator) is a kind of __reset__(). In some cases, it is only needed to allow a new iteration from start. But it may even be needed to set some startup data the first time. __reset__() would thus be called once before the first call to next(). (Sure, "reset" may not be the best term. Maybe "begin" or "startup"? The sense is: "Prepare to yield the first item!")
In absence of such a startup mechanism, I end up using __call__ instead: Example:

class Powers(object):
    def __init__(self, exponent):
        self.exponent = exponent
    def next(self):
        n = self.n + 1
        if (self.max is not None) and (n > self.max):
            raise StopIteration
        self.n = n
        return n*n
    def __call__(self, min=1,max=None):
        self.n = min-1
        self.max = max
        return self	#.__iter__()
    def __iter__(self):
        return self

tripleCubes = []
cubes = Powers(3)
for sq in cubes(7,17):
    if sq%3 == 0:
        tripleCubes.append(sq)
print tripleCubes    # ==> [81, 144, 225]

__iter__() could be used directly if it would allow "free" args in addition to self (in this case: def __iter__(self, min=0,max=None). This beeing impossible, an aditional method seems to be needed.

To sum up, I would enjoy beeing able to write Powers using a scheme like:
class Powers(object):
    def __init__(self, exponent):
        self.exponent = exponent
    def __reset__(self, min=1,max=None):
        self.n = min-1
        self.max = max
    def __next__(self):
        n = self.n + 1
        if (self.max is not None) and (n > self.max):
            raise StopIteration
        self.n = n
        return n*n

This matches the overall idea of iterable for me.

Denis
-- 
________________________________

la vita e estrany

spir.wikidot.com




More information about the Python-ideas mailing list