Python中except:和except Exception之间的区别,例如e:


140

以下两个代码段都执行相同的操作。他们捕获每个异常并执行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

两种结构到底有什么区别?


7
@ user2725093这不是同一个问题。您与之链接的人问except Exception, e:和之间有什么区别except Exception as e:。这个问题问except:和之间有什么区别except Exception as e:
丹尼斯

Answers:


155

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

>>> 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()
>>> 

有关更多信息,请参阅文档的“ 内置异常”部分和本教程的“ 错误与异常”部分。


21
好吧,这里没有魔术。Exception源自BaseException,这就是为什么except Exception不赶上BaseException。如果您编写except BaseException,它也会被抓住。裸露except无所不能。
fjarri 2013年

2
我应该指出,裸露except必须在一系列except块中排在最后,而如果放在except Exception其他except块之前不会出现错误:它们只会被静默忽略(如果它们处理Exception子类)。需要提防的东西。
Vanessa Phipps 2014年

@MatthewPhipps就是这样,不是吗?如case语句或if-else块,执行将跳至与...匹配的第一个条件
2014年

1
@Basic只是指出了裸色except和色之间的另一个区别except Exception。现在“需要注意的事情”看起来有些怪异,但是当时我希望Python能够选择最具体的except块,无论它位于何处,而且对于发现其他情况还是有些失望。
Vanessa Phipps 2014年

还值得注意的是,仅当您不关心异常是什么或希望以有意义的方式处理它时,才应使用第二种形式。
乔什J

51
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


except(Exception)永远不会发现KeyboardInterrupt错误。as e与它没有任何关系。
pandita 2013年

2
我从来没有说过。我从未提到过as e,因为我认为它的作用很明显。
Veedrac

2
是否有人会捕获BaseException并且知道他们在做什么?
达沃斯

2
@Davos是的,在进行临时日志记录时,或者在向用户提供不希望异常SystemExitKeyboardInterrupt逃脱异常的控制台时,您可能更喜欢它。这种情况并不常见,但确实会发生。
Veedrac '18

14

除某些例外外,还有其他区别,例如KeyboardInterrupt。

阅读PEP8

仅有的except:子句将捕获SystemExit和KeyboardInterrupt异常,这使得使用Control-C中断程序更加困难,并且可以掩盖其他问题。如果要捕获所有表示程序错误的异常,请使用Exception:除外(裸除等效于BaseException:除外)。


3

使用第二种形式会在块范围内为您提供一个变量(根据as示例中的子句命名e),并except绑定了异常对象,因此您可以在异常中使用信息(类型,消息,堆栈跟踪等)来在更特别的庄园中处理例外情况。


1

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

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”语法可以访问许多“事物”。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.