Question

Unexpected generator behaviour when not assigned to a variable

Could someone explain the difference between these two executions? Here is my generator function:

def g(n):
    try:
        yield n
        print("first")
    except BaseException as e:
        print(f"exception {e}")
        raise e
    finally:
        print("second")

When I execute:

>>> a = next(g(2))
exception
second

Could someone explain why a = next(g(2)) raises an exception and what is the difference with the below execution?

>>> x = g(2)
>>> next(x)
2

My expectation was that when I execute a = next(g(2)) the function g(2) returns a generator and next() returns the first yield of the generator but apparently an exception is raised. Why is this happening?

 3  54  3
1 Jan 1970

Solution

 4

In the first scenario, the generator is garbage collected after next(), triggering finally and raising an exception. In the second, the generator is kept by x, preventing this and allowing normal operation.

Edit:

GeneratorExit exception is thrown when a generator is closed, after that finally block will be exceuted.

Also, from the docs:

If the generator is not resumed before it is finalized (by reaching a zero reference count or by being garbage collected), the generator-iterator’s close() method will be called, allowing any pending finally clauses to execute.

2024-07-05
Coding Enthusiast