12

I have a class in python, which has an iterable as instance variable. I want to iterate the instances of the class by iterating over the embedded iterable.

I implemented this as follows:

def __iter__(self):
    return self._iterable.__iter__()

I don't really feel that comfortable calling the __iter__() method on the iterable, as it is a special method. Is this how you would solve this problem in python or is there a more elegant solution?

1
  • 1
    You might want to keep an eye on PEP 380 (python.org/dev/peps/pep-0380) which will make this possible with yield from self._iterable (this is accepted for inclusion in 3.3). Commented Mar 5, 2012 at 20:44

1 Answer 1

23

The "best" way to way to delegate __iter__ would be:

def __iter__(self):
    return iter(self._iterable)

Alternately, it might be worth knowing about:

def __iter__(self):
    for item in self._iterable:
        yield item

Which will let you fiddle with each item before returning it (ex, if you wanted yield item * 2).

And as @Lattyware mentions in the comments, PEP380 (slated for inclusion in Python 3.3) will allow:

def __iter__(self):
    yield from self._iterable

Note that it may be tempting to do something like:

def __init__(self, iterable):
    self.__iter__ = iterable.__iter__

But this won't work: iter(foo) calls the __iter__ method on type(foo) directly, bypassing foo.__iter__. Consider, for example:

class SurprisingIter(object):
    def __init__(self):
        self.__iter__ = lambda self: iter("abc")

    def __iter__(self):
        return iter([1, 2, 3])

You would expect that list(SurprisingIter()) would return ["a", "b", "c"], but it actually returns [1, 2, 3].

Sign up to request clarification or add additional context in comments.

1 Comment

There is a typo in the PEP380 variant, which I prefer. It should be def __iter__(self): yield from self._iterable

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.