Return value of the generator method throw

Viewed 75

The help of throw says:

throw(...) method of builtins.generator instance throw(typ[,val[,tb]]) -> raise exception in generator, return next yielded value or raise StopIteration

"return next yielded value" this is my problem!

Let's have a look at this example:

def gen():
    counter = 1
    while True:
        try:
            yield counter
            counter += 1
        except Exception as e:
            print("Exception and tpye: ", e, type(e))
            

x = gen()
print("Result of first next call: ", next(x))
res = x.throw(ValueError("Whatever!"))
print("result of throw call: ", res)
print("Result of first next call: ", next(x))

The output looks like this:

Result of first next call:  1
Exception and tpye:  Whatever! <class 'ValueError'>
result of throw call:  1
Result of first next call:  2

Shouldn't the return value of throw be 2 instead of one? The help file says "return NEXT yielded value2" not "return again previously yielded value"

I am afraid that I got something completely wrong?

2 Answers

When you use gen.throw(...), the exception is raised at the yield statement.

While you catch it, the following incrementation of counter is not executed. You can move it into a finally:-clause to ensure that no matter what, you always increment counter:

def gen():
    counter = 1
    while True:
        try:
            yield counter
        except Exception as e:
            print("Exception and type: ", e, type(e))
        finally:
            counter += 1

Put the counter before the yield:

counter += 1
yield counter

Otherwise, the first yield will be with counter==1.

Related