Cyker
Cyker

Reputation: 10914

Python: try...except...finally clauses in generators

Code

def gen():
    try:
        for i in range(5):
            yield i
    except Exception as e:
        print('Caught: ' + str(e))
    finally:
        print('I am done')

for x in gen():
    print(x)
    if x == 2:
        raise Exception('Catch me?')

Output

0
1
2
I am done
Traceback (most recent call last):
  File "test.py", line 13, in <module>
    raise Exception('Catch me?')
Exception: Catch me?

Question

Why does the code execute finally clause but not except clause?

Please give explanations with references.

Upvotes: 3

Views: 1561

Answers (1)

BrenBarn
BrenBarn

Reputation: 251373

The body of the generator function will only be run between iterations of the for loop. That is, the for loop means something like:

  1. Get next value from generator
  2. Run loop body
  3. Go back to step 1

Only step 1 involves actually running code inside the generator function. Since the code inside try block in the generator function doesn't raise any exceptions, the except clause has nothing to catch. The finally clause executes because it always executes (that's what finally is for).

Using a loop over a generator doesn't mean that the whole loop body runs "inside" the generator function. It just means one value at a time is grabbed from the generator until it's exhausted. The loop body still executes in its own scope, separate from that of the generator function.

Upvotes: 4

Related Questions