2

Given a simple generator:

def myGenerator(max):
    for i in range(max):
        yield i

It can be used like:

>>> gen = myGenerator(10)
>>> next(gen)
0
>>> next(gen)
1

When I execute close() on the generator, all subsequent calls to next result in a StopIteration exception.

>>> gen.close()
>>> next(gen)
StopIteration exception

Can the generator take notice on that? yield does not throw an exception. I'm looking for something like:

def myGenerator(max):
    for i in range(max):
        try:
            yield i
        except CloseIteration as ex:
            print("I got closed")
jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Paebbels
  • 15,573
  • 13
  • 70
  • 139

1 Answers1

1

As Jon mentioned in the comment, calling close() raises a GeneratorExit exception, which you can watch for:

In [1]: def mygenerator(max):
   ...:     try:
   ...:         for i in range(max):
   ...:             yield i
   ...:     except GeneratorExit:
   ...:         print('I got closed')
   ...:         raise
   ...:     

In [2]: gen = mygenerator(10)

In [3]: next(gen)
Out[3]: 0

In [4]: next(gen)
Out[4]: 1

In [5]: gen.close()
I got closed
Lev Levitsky
  • 63,701
  • 20
  • 147
  • 175
  • Interesting... without the inner try except block, there is no exception.... Please add the link to the Python manual for other readers. Thanks. – Paebbels Mar 06 '16 at 21:56
  • @Paebbels that's because it's part of the generator's job to catch that exception (indeed it complains if you catch it and don't re-`raise`). – jonrsharpe Mar 06 '16 at 21:57