0

I have found an elegant solution for the problem of returning a final information after generator exhaustion, which is to put the desired content inside StopIteration. This require manually raising the Exception at the end of the generator function. However, it seems not possible to caught from the outside. The only way it worked was with a custom exception, which breaks the generator protocol for anyone not interested in the returned value (in a for statement for instance).

def generator():
    for i in range(3):
        print('inside', i)
        yield i
    print('raising...')
    raise StopIteration('<<Some accumulated result.>>')

p = generator()
try:
    while True:
        print('\n Trying...')
        print('outside', next(p))
except StopIteration as e:
    print('handling', e.arg

Output:

Trying...
inside 0
outside 0

Trying...
inside 1
outside 1

Trying...
inside 2
outside 2

Trying...
raising...
RuntimeError: generator raised StopIteration

Expected output:

Trying...
inside 0
outside 0

Trying...
inside 1
outside 1

Trying...
inside 2
outside 2

Trying...
raising...
handling ('<<Some accumulated result.>>')
dawid
  • 663
  • 6
  • 12

1 Answers1

0

Actually, the generator return value seems to be put inside the exception by default:

def generator():
    for i in range(3):
        print('inside', i)
        yield i
    print('raising...')
    return '<<Some accumulated result.>>'


p = generator()
try:
    while True:
        print('\n Trying...')
        print('outside', next(p))
except StopIteration as e:
    print('handling', e.args)

Output:

Trying...
inside 0
outside 0

Trying...
inside 1
outside 1

Trying...
inside 2
outside 2

Trying...
raising...
handling ('<<Some accumulated result.>>')
dawid
  • 663
  • 6
  • 12