为什么 "except:" 能够捕捉到这个错误,而 "except Exception, e:" 却不能?

Why is "except:" able to catch this error but not "except Exception, e:"?

我有以下文件:

from fabric.api import env, execute, run

env.hosts = ['1.2.3.4']

def taskA():
    run('ls')

def main():
  try:
    execute(taskA)
  except:
    print "Exception Caught"

main()

当我 运行 时,我能够看到 "Exception Caught" 打印:

$ python test.py
[1.2.3.4] Executing task 'taskA'
[1.2.3.4] run: ls

Fatal error: Timed out trying to connect to 1.2.3.4 (tried 1 time)

Underlying exception:
    timed out

Aborting.
Exception Caught

然而,当我将其切换为:

def main():
  try:
    execute(taskA)
  except Exception, e:
    print "Exception Caught", e

main()

我没有看到异常被捕获:

[1.2.3.4] run: ls

Fatal error: Timed out trying to connect to 1.2.3.4 (tried 1 time)

Underlying exception:
    timed out

Aborting.

为什么我能够在上面的代码中捕获错误而不是在下面的代码中捕获错误?

当你使用except Exception, e时,它

doesn't catch BaseException or the system-exiting exceptions SystemExit, KeyboardInterrupt and GeneratorExit

其中 except 捕获所有异常类型。参见 Difference between except: and except Exception as e: in Python

因此,您在使用 except 时会看到 "Exception Caught",但在使用 except Exception, e

时却看不到

来自晶圆厂docs

If a Python exception is thrown, fab aborts with an exit status of 1.

此异常并非源自 Exception。它看起来像一个 SystemExit,直接派生自 BaseExceptionexcept Exception 只捕获 Exception.

的实例

如果你真的想捕获所有异常,你可以用

except BaseException as e:

SystemExitsys.exit 和一些类似的函数抛出,导致解释器关闭(或至少结束线程),同时仍然有 运行 __exit__ 方法和finally 块。也可以手动抛出。

BaseException 存在,因此 SystemExit 和一些类似的异常不会被通常不打算处理它们的 except Exception 块捕获。它类似于 Java 的 Throwable。就我个人而言,我希望普通的 except: 块不会被捕获 BaseException;它首先破坏了 BaseException 的一些目的。