205

以下两个代码片段都做同样的事情。他们捕获每个异常并执行except:块中的代码

片段 1 -

try:
    #some code that may throw an exception
except:
    #exception handling code

片段 2 -

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code

两种构造的具体区别是什么?

4

5 回答 5

223

在第二个中,您可以访问异常对象的属性:

>>> def catch():
...     try:
...         asd()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
global name 'asd' is not defined ("global name 'asd' is not defined",)

但它没有捕获BaseException或系统退出异常SystemExitKeyboardInterrupt并且GeneratorExit

>>> def catch():
...     try:
...         raise BaseException()
...     except Exception as e:
...         print e.message, e.args
... 
>>> catch()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in catch
BaseException

一个裸露的除外:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 

有关详细信息,请参阅文档的内置异常部分和教程的错误和异常部分。

于 2013-09-24T13:16:29.843 回答
74
except:

接受所有例外,而

except Exception as e:

仅接受您要捕获的异常。

下面是一个你不想抓住的例子:

>>> try:
...     input()
... except:
...     pass
... 
>>> try:
...     input()
... except Exception as e:
...     pass
... 
Traceback (most recent call last):
  File "<stdin>", line 2, in <module>
KeyboardInterrupt

第一个沉默了KeyboardInterrupt

这是一个快速列表:

issubclass(BaseException, BaseException)
#>>> True
issubclass(BaseException, Exception)
#>>> False


issubclass(KeyboardInterrupt, BaseException)
#>>> True
issubclass(KeyboardInterrupt, Exception)
#>>> False


issubclass(SystemExit, BaseException)
#>>> True
issubclass(SystemExit, Exception)
#>>> False

如果您想抓住其中任何一个,最好这样做

except BaseException:

指出你知道你在做什么。


所有异常BaseException都来自.Exception

于 2013-09-24T13:17:35.860 回答
16

有一些例外情况有所不同,例如KeyboardInterrupt。

阅读PEP8

一个简单的 except: 子句将捕获 SystemExit 和 KeyboardInterrupt 异常,使使用 Control-C 中断程序变得更加困难,并且可以掩盖其他问题。如果要捕获所有表明程序错误的异常,请使用 except Exception: (bare except 等价于 except BaseException:)。

于 2013-09-24T13:18:08.893 回答
6

另一种看待这个的方式。查看异常的详细信息:

In [49]: try: 
    ...:     open('file.DNE.txt') 
    ...: except Exception as  e: 
    ...:     print(dir(e)) 
    ...:                                                                                                                                    
['__cause__', '__class__', '__context__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__suppress_context__', '__traceback__', 'args', 'characters_written', 'errno', 'filename', 'filename2', 'strerror', 'with_traceback']

使用“as e”语法可以访问很多“事物”。

此代码仅用于显示此实例的详细信息。

于 2020-02-24T22:38:23.973 回答
4

使用第二个片段会在块范围内为您提供一个变量(在您的示例中基于as子句命名e),except异常对象绑定到它,因此您可以使用异常中的信息(类型、消息、堆栈跟踪等)来在更特别定制的庄园中处理异常。

于 2013-09-24T13:18:14.113 回答