使用异常处理解释 generator.close()

Ric*_*ick 4 python generator

我正在阅读 python 文档https://docs.python.org/3/reference/expressions.html about generator.close()

我对文档的翻译是:

##generator.close()

GeneratorExit在生成器函数暂停的位置引发 a 。

  1. 如果生成器函数然后优雅地退出:

1.1 已经关闭,
1.2 或引发GeneratorExit(通过不捕获异常),

close 返回给它的调用者。

  1. 如果生成器产生一个值,则 aRuntimeError被提高。

  2. 如果生成器引发任何其他异常,则会将其传播给调用者。

close() 如果由于异常或正常退出,生成器已经退出,则不执行任何操作。


我不明白该close()行为如何对应于文档。

>>> def echo(value=None):
...     print("Execution starts when 'next()' is called for the first time.")
...     try:
...         while True:
...             try:
...                 value = (yield value)
...             except Exception as e:
...                 value = e
...     finally:
...         print("Don't forget to clean up when 'close()' is called.")
...
>>> generator = echo(1)
>>> next(generator)
Execution starts when 'next()' is called for the first time.
>>> generator.close()
Don't forget to clean up when 'close()' is called.
Run Code Online (Sandbox Code Playgroud)

哪个规则适用于generator.close()?我很迷惑。

我的理解:

  1. generator.close()引发GeneratorExit异常
  2. GeneratorExit被捕获except Exception as e:并循环继续
  3. value = (yield value) 执行
  4. 根据上述规则2,aRuntimeError将被提高。

但情况似乎并非如此。

请告诉我里面发生了什么。

Mis*_*agi 6

GeneratorExit不是继承自Exception,而是来自更根本的BaseException。因此,它不会被您的except Exception块捕获。

所以你的假设2是错误的。生成器通过案例 1.3 优雅地退出,因为GeneratorExit它没有停止。

  1. GeneratorExit在抛出(yield value)
  2. try: except Exception as e:检查当前的异常是否是子类Exception。由于情况并非如此,因此它展开。
  3. while True:由于当前异常退绕。
  4. try: finally:退绕,运行其finally:块。这会导致显示消息。
  5. 生成器以当前异常退出,即GeneratorExit
  6. generator.close检测并抑制GeneratorExit.