除了以外的区别:和除了Ex:e:在Python中

nar*_*shi 114 python python-3.x

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

小片1 -

try:
    #some code that may throw an exception
except:
    #exception handling code
Run Code Online (Sandbox Code Playgroud)

小片2 -

try:
    #some code that may throw an exception
except Exception as e:
    #exception handling code
Run Code Online (Sandbox Code Playgroud)

两种结构的区别是什么?

agf*_*agf 127

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

>>> 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",)
Run Code Online (Sandbox Code Playgroud)

但它没有捕获BaseException或系统退出异常SystemExit,KeyboardInterrupt并且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
Run Code Online (Sandbox Code Playgroud)

哪一个除了:

>>> def catch():
...     try:
...         raise BaseException()
...     except:
...         pass
... 
>>> catch()
>>> 
Run Code Online (Sandbox Code Playgroud)

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

  • 嗯,这里没有魔力.``Exception``派生自``BaseException``,这就是为什么``除了Exception``没有捕获``BaseException``.如果你写``除了BaseException``,它也会被捕获.裸露的``除了``只是抓住了一切. (17认同)
  • 我应该指出,一个空的 `except` 必须在一系列 `except` 块的最后,而如果你将 `except Exception` 放在其他 `except` 块之前,你不会得到错误:它们只会被忽略静默(如果他们处理 `Exception` 子类)。有什么需要注意的。 (2认同)

Vee*_*rac 47

except:
Run Code Online (Sandbox Code Playgroud)

接受所有例外,而

except Exception as e:
Run Code Online (Sandbox Code Playgroud)

只接受你的例外意味着赶上.

这是一个你不应该抓住的例子:

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

第一个沉默了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
Run Code Online (Sandbox Code Playgroud)

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

except BaseException:
Run Code Online (Sandbox Code Playgroud)

指出你知道你在做什么.


所有异常的干BaseException,而那些你命中注定要赶一天到一天(那些会被抛出程序员)也继承从Exception.

  • 我从来没有说过它.我之前没有提到`as e`,因为我认为它的作用很明显. (2认同)
  • 是否存在一个人会捕获BaseException并且知道他们在做什么的情况? (2认同)
  • @Davos是的,在进行瞬态日志记录时,或者在向用户提供控制台时,您可能不希望它逃脱诸如SystemExit或KeyboardInterrupt之类的异常,您可能会喜欢它。这种情况并不常见,但确实会发生。 (2认同)

Die*_*anz 13

某些例外情况存在差异,例如KeyboardInterrupt.

阅读PEP8:

一个裸的except:子句将捕获SystemExit和KeyboardInterrupt异常,使得用Control-C中断程序变得更加困难,并且可以掩盖其他问题.如果你想捕获所有发出程序错误信号的异常,请使用除Exception :(裸除了除了BaseException之外).


Sil*_*Ray 5

使用第二个片段会在块作用域中为您提供一个变量(as在您的示例中根据子句命名eexcept,并将异常对象绑定到该变量,以便您可以使用异常中的信息(类型、消息、堆栈跟踪等)来在更专门定制的庄园中处理异常。


jou*_*ell 5

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

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']
Run Code Online (Sandbox Code Playgroud)

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

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