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?
To create an object/class as an iterator you have to implement the methods __iter__() and __next__() to your object. As you have learned in the Python Classes/Objects chapter, all classes have a function called __init__() , which allows you to do some initializing when the object is being created.
Iterator objects in python conform to the iterator protocol, which basically means they provide two methods: __iter__() and __next__() . The __iter__ returns the iterator object and is implicitly called at the start of loops. The __next__() method returns the next value and is implicitly called at each loop increment.
To make your class Iterable we need to override __iter__() function inside our class i.e. This function should return the object of Iterator class associated with this Iterable class. Contains List of Junior and senior team members and also overrides the __iter__() function. It overrides the __iter__() function.
The __iter__() method returns the iterator object itself. If required, some initialization can be performed. The __next__() method must return the next item in the sequence. On reaching the end, and in subsequent calls, it must raise StopIteration .
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]
.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With