如果调用者在其上调用了 close() ,生成器能否注意到?

Can a generator take notice if a caller has called close() on it?

给定一个简单的生成器:

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

可以这样使用:

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

当我在生成器上执行 close() 时,对 next 的所有后续调用都会导致 StopIteration 异常。

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

发电机能注意到吗? yield 不会抛出异常。我正在寻找类似的东西:

def myGenerator(max):
    for i in range(max):
        try:
            yield i
        except CloseIteration as ex:
            print("I got closed")

正如 Jon 在评论中提到的,calling close() raises a GeneratorExit exception,您可以关注:

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