It is sometimes necessary for a generator function to expose state. In those situations it is advised to wrap the generator function as method __iter__
in a class. Here is an example:
class C:
def __iter__(self):
for i in range(4):
yield i
self.state = i
It is convenient to use this in a for loop since the for loop will call iter() on the object, however, the object itself is not an iterator, so you cannot do this:
c = C()
print(next(c))
Which is inconvenient. To get around this inconvenience I have come up with the following class:
class C:
def __init__(self):
self.next = self.__iter__().__next__
def __iter__(self):
for i in range(4):
yield i
self.state = i
def __next__(self):
return self.next()
Usage example:
c = C()
while 1:
try:
num = next(c)
print(num)
if num == 2:
print("state:", c.state)
except Exception:
break
Is this the best way to design the class? I haven't seen this technique used anywhere else so I'm wondering why everyone else isn't using it, since the C objects can be used both as iterators and as iterables.