【问题标题】:Difference between throwing GeneratorExit and calling close() in python在 python 中抛出 GeneratorExit 和调用 close() 之间的区别
【发布时间】:2020-09-26 04:29:49
【问题描述】:

感谢您提出我的问题。我试图把我的问题说清楚,但如果因为我的英语还有不清楚的部分,请告诉我。

我正在研究 Python 协程,并且读到在生成器上调用 close() 方法类似于将 GeneratorExit 扔给生成器。所以我尝试如下。

def gen(n):
    while True:
        yield n

test = gen(10)
next(test)
test.throw(GeneratorExit)

然后发生GeneratorExit 异常。但是,当我尝试test.close() 时,它没有引发任何异常。

所以我稍微修改了上面的代码;

def gen(n):
    while True:
        try:
            yield n
        except GeneratorExit:
            break
test = gen(10)
next(test)
test.throw(GeneratorExit)

在处理GeneratorExit 时,它没有被引发,但发生了StopIteration 异常。我知道如果没有更多的收益,StopIteration 异常就会上升。但是,当我使用修改后的代码再次尝试 test.close() 时,它没有被提出。

您能告诉我抛出GeneratorExit 和调用close() 方法有什么区别吗?

更准确地说,我可以理解为什么test.throw(GeneratorExit) 会出现StopIterationGeneratorExit 异常,但不知道为什么使用test.close() 时不会引发这些异常

谢谢。

【问题讨论】:

  • 您必须在 except 块中重新引发异常。简单的break 不处理异常。
  • 感谢您的评论。我试过了,但是我像上面写的未修改的代码一样再次提出了GeneratorExit。

标签: python generator


【解决方案1】:

GeneratorExit 出现在以下两种情况之一:

  • 当你打电话给close
  • 当 python 调用该生成器的垃圾收集器时。

(见documentation

你可以在下面的代码中看到:

def gen(n):
    while True:
        try:
            yield n
        except GeneratorExit:
            print("gen caught a GeneratorExit exception")
            break # (throws a StopIteration exception)

def gen_rte(n):
    while True:
        try:
            yield n
        except GeneratorExit:
            print("gen_rte caught a GeneratorExit exception")
            # No break here - we'll get a runtime exception

test = gen(10)
print(next(test))
==> 10

test.close()
==> gen caught a GeneratorExit exception  


test = gen(15)
print(next(test))
==> 15
test.throw(GeneratorExit)

==> gen 捕获了一个 GeneratorExit 异常 回溯(最近一次通话最后): 文件“...”,第 20 行,在 test.throw(GeneratorExit) StopIteration(这是'break'语句的结果

test = gen_rte(20)
print(next(test))
==> 20

test.close()
==> 
    gen_rte caught a GeneratorExit exception
    Traceback (most recent call last):
      File "...", line 24, in <module>
        test.close()
    RuntimeError: generator ignored GeneratorExit

最后,在程序结束之前还有另一个GeneratorExit 异常——我相信这是垃圾收集器的结果。 gen_rte 捕获到 GeneratorExit 异常 异常被忽略: RuntimeError: 生成器忽略了 GeneratorExit

【讨论】:

    猜你喜欢
    • 2014-05-31
    • 2013-02-10
    • 2011-03-01
    • 2022-12-03
    • 2019-12-21
    • 1970-01-01
    • 1970-01-01
    • 2016-03-09
    • 2013-07-17
    相关资源
    最近更新 更多