抛出GeneratorExit与在python中调用close()之间的区别

问题描述 投票:3回答:1

感谢您打开我的问题。我试图使我的问题更清楚,但是如果由于我的英语仍然有不清楚的部分,请告诉我。

我正在研究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()方法之间的区别是什么?

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

谢谢。

python generator
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.