gpt4 book ai didi

python - 为什么 GeneratorExit 和 StopIteration 有不同的基类?

转载 作者:太空狗 更新时间:2023-10-29 23:58:31 25 4
gpt4 key购买 nike

我查看了内置 python 异常的层次结构,我注意到 StopIterationGeneratorExit 有不同的基类:

BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
+-- Warning

或者在代码中:

>>> GeneratorExit.__bases__
(<type 'exceptions.BaseException'>,)
>>> StopIteration.__bases__
(<type 'exceptions.Exception'>,)

当我转到每个异常的具体描述时,我可以阅读以下内容:

https://docs.python.org/2/library/exceptions.html#exceptions.GeneratorExit

exception GeneratorExit

Raised when a generator‘s close() method is called. It directly inherits from BaseException instead of StandardError since it is technically not an error.

https://docs.python.org/2/library/exceptions.html#exceptions.StopIteration

exception StopIteration

Raised by an iterator‘s next() method to signal that there are no further values. This is derived from Exception rather than StandardError, since this is not considered an error in its normal application.

我不是很清楚。两者的相似之处在于它们不通知错误,而是一个改变代码流的“事件”。所以,它们在技术上不是错误,我知道它们应该与其他异常分开......但为什么一个是 BaseException 的子类,另一个是 的子类异常

总的来说,我总是认为 Exception 子类是错误的,当我写一个盲目的 try: except: (例如调用第三方代码)时,我总是 try catch Exception,但也许这是错误的,我应该捕获 StandardError

最佳答案

使用 try: ... except Exception: ... block 是很常见的。

如果 GeneratorExit 继承自 Exception,您将遇到以下问题:

def get_next_element(alist):
for element in alist:
try:
yield element
except BaseException: # except Exception
pass

for element in get_next_element([0,1,2,3,4,5,6,7,8,9]):
if element == 3:
break
else:
print(element)

0
1
2
Exception ignored in: <generator object get_next_element at 0x7fffed7e8360>
RuntimeError: generator ignored GeneratorExit

这个例子非常简单,但想象一下在 try block 中有一个更复杂的操作,如果失败,它会简单地忽略问题(或打印一条消息)并进入下一个迭代。

如果您要捕获通用异常,您最终会阻止生成器的用户在没有得到 RuntimeError 的情况下中断循环。

更好的解释是here .

编辑:在这里回答,因为评论太长了。

我宁愿说相反的话。 GeneratorExit 应该继承自 Exception 而不是 BaseException。当您捕获 Exception 时,您基本上想要捕获几乎所有内容。 BaseExceptionPEP-352状态,是为了那些需要被“排除”的异常,以允许用户从否则会捕获它们的代码中逃脱。通过这种方式,您仍然可以使用 CTRL-C 运行代码。 GeneratorExit 属于该类别以打破循环。关于它的有趣对话 comp.lang.python .

关于python - 为什么 GeneratorExit 和 StopIteration 有不同的基类?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31406654/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com