在python中,except Exception as ex
或except BaseException as ex
是否与except:
相同,但是你得到了对异常的引用?
根据我的理解BaseException
是更新的默认全能。
除此之外,为什么你只想要一个except:
条款?
答案 0 :(得分:5)
除了Pokémon exception handling* being a bad idea之外,还有一些差异。
except Exception:
和except BaseException:
都不会捕获旧式类异常(仅限Python 2):
>>> class Foo(): pass
...
>>> try:
... raise Foo()
... except Exception:
... print 'Caught'
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
__main__.Foo: <__main__.Foo instance at 0x10ef566c8>
>>> try:
... raise Foo()
... except BaseException:
... print 'Caught'
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
__main__.Foo: <__main__.Foo instance at 0x10ef56680>
>>> try:
... raise Foo()
... except:
... print 'Caught'
...
Caught
因为旧式对象不是来自BaseException
或Exception
。在任何情况下,这都是永远不会使用不是Exception
派生的自定义异常的理由。
接下来,有三个例外来自BaseException
,但不来自Exception
;在大多数情况下,你不想抓住那些。 SystemExit
,KeyboardInterrupt
和GeneratorExit
不是您在异常处理的正常过程中想要捕获的异常。如果您使用except BaseException:
,则会抓住这些内容,except Exception
不会。
* 神奇宝贝异常处理,因为你必须全部抓住。
答案 1 :(得分:3)
如果你真的不在乎失败的原因或信息是什么,你可以使用裸except:
。有时,如果您尝试访问某些可能存在或可能不存在或正在工作的功能,这将非常有用,如果它失败,您计划优雅地降级到某些其他代码路径。在这种情况下,错误类型或字符串不会影响您将要执行的操作。
答案 2 :(得分:3)
三者之间的区别是:
except
抓住了所有内容,包括系统退出的内容,例如KeyboardInterrupt
; except Exception[ as ex]
将捕获Exception
的任何子类,它应该是您的所有用户定义的异常,而内置的所有非系统退出;和except BaseException[ as ex]
将像裸except
一样,完全捕捉所有内容。一般情况下,我建议使用2.(理想情况下,在您捕获特定/“预期”错误之后作为后备),因为这允许那些系统退出异常渗透到顶层。正如您所说,2.和3的as ex
部分允许您在处理错误时检查错误。
有一篇关于“除了”here的邪恶的有用文章。
答案 3 :(得分:2)
事实并非如此,没有。
如果您查看有关内置异常的Python文档(特别是this bit),您会看到哪些异常从哪里继承。如果您使用原始的除了:,它将捕获每个引发的异常,甚至包括您几乎肯定不想捕获的KeyboardInterrupt;如果您使用捕获BaseException,除了BaseException为exp:,因为所有异常都从它继承。
如果你想要捕获所有程序运行时异常,那么使用除Exception为exp:是正确的,因为它不会捕获你想要结束的异常类型程序(如KeyboardInterrupt)。
现在,人们会告诉你以这种方式捕捉所有异常是一个坏主意,而且通常他们是对的;但是,如果您有一个处理大批数据的程序,您可能理所当然地希望它在异常情况下不会退出。只要你正确处理异常(即记录它并确保用户看到异常发生),但从不只是传递;如果你的程序产生了你不知道的错误,它确实会做出奇怪的事情!
答案 4 :(得分:0)
除此之外,为什么你只想要一个
except:
条款?
简短回答:你不希望这样。
更长的答案:使用裸except:
会消除区分异常的能力,甚至可以更轻松地处理异常对象。因此,您通常始终使用except ExceptionType as e:
形式。