Shankar Shankar - 3 months ago 16
Python Question

Unable to return a generator instance. why?

I tried to return a generator function instance and i am getting a StopIteration error. Why?

here is my code:

>>> def gen(start, end):
... '''generator function similar to range function'''
... while start <= end:
... yield start
... start += 1
...
>>> def check(ingen, flag=None):
... if flag:
... for n in ingen:
... yield n*2
... else:
... return ingen
...
>>> # Trigger else clause in check function
>>> a = check(gen(1,3))
>>> next(a)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
StopIteration: <generator object gen at 0x7f37dc46e828>


It looks like the generator is somehow exhausted before the else clause is returns the generator.

It works fine with this function:

>>> def check_v2(ingen):
... return ingen
...
>>> b = check_v2(gen(1, 3))
>>> next(b)
1
>>> next(b)
2
>>> next(b)
3

Answer

In Python, if yield is present in a function, then Python treats it as a generator. In a generator, any returns raise StopIteration with the returned value. This is a new feature in Python 3; see PEP 380 and here. check_v2 works because it doesn't contain a yield and is therefore a normal function.

There are two ways to accomplish what you want:

  • Change the return to a yield in check.
  • Have the caller trap StopIteration:

    try: next(a) except StopIteration as ex: print(ex.value)

Comments