我写了一个关于Python生成器的测试程序.但是我得到了一个不期望的错误.我不知道如何解释它.我来告诉你代码:
def countdown(n):
logging.debug("Counting down")
while n > 0:
try:
yield n
except GeneratorExit:
logging.error("GeneratorExit")
n -= 1
if __name__ == '__main__':
c = countdown(10)
logging.debug("value: %d", c.next())
Run Code Online (Sandbox Code Playgroud)
我认为应该没有任何问题.但输出是:
# ./test.py
[2015/06/16 04:10:49] DEBUG - Counting down
[2015/06/16 04:10:49] DEBUG - value: 10
[2015/06/16 04:10:49] ERROR - GeneratorExit
Exception RuntimeError: 'generator ignored GeneratorExit' in <generator object countdown at 0x7f9934407640> ignored
Run Code Online (Sandbox Code Playgroud)
为什么最后一行有错误.我不知道为什么我触发了GeneratorExit异常.我错过了什么东西生成器吗?我还将代码输入到交互式python shell中,一切正常.怎么会发生这种情况?
use*_*ica 25
假设您有以下生成器:
def gen():
with open('important_file') as f:
for line in f:
yield line
Run Code Online (Sandbox Code Playgroud)
而你next一次扔掉它:
g = gen()
next(g)
del g
Run Code Online (Sandbox Code Playgroud)
生成器的控制流永远不会离开with块,因此文件不会关闭.为了防止这种情况,当一个生成器被垃圾收集时,Python会调用它的close方法,这会GeneratorExit在生成器最后yield编辑的位置引发异常.此异常旨在触发任何无法运行的finally块或上下文管理器__exit__.
当你抓住GeneratorExit并继续前进时,Python会发现生成器没有正常退出.由于这可能表明资源未正确发布,因此Python将其报告为RuntimeError.
当在程序结束时对生成器对象进行垃圾收集时,close()会调用其方法,这会GeneratorExit在生成器内引发异常.通常这不会被捕获并导致发电机退出.
因为你捕获异常并继续产生另一个值,这会导致a RuntimeError.如果你捕获GeneratorExit异常,你需要重新加载它,或退出函数而不产生任何其他东西.
| 归档时间: |
|
| 查看次数: |
9325 次 |
| 最近记录: |