如何处理异常处理程序中引发的自定义异常?

How to handle a custom exception raised inside an exception handler?

如果我 运行 以下 Python 脚本并假设我的文件读取将失败,IOError 处理程序将引发自定义异常,但我不确定我应该如何处理引发自定义异常。有人可以帮忙吗?

class CustomIOError(IOError):
  def __init__(self, msg):
    super(CustomIOError, self).__init__()
    self.error_msg = msg

try:
  # Open file to read
  with open(fileName) as f:
    for line in f:
    print line,
except IOError :
  raise CustomIOError('Exception message')

#  except CustomIOError :
#    sys.exit(0)

另外,如果Python支持多态性,为什么我不能直接处理base class的异常,而派生class的异常处理程序?

try:
  raise IOError
except CustomIOError:
  pass

这行不通,程序执行将在打印一部分堆栈跟踪后终止。

  1. 预计子类型无法捕获超类型错误
  2. 从 A 部分除外的部分抛出的异常不能被 A 旁边的部分捕获

因此,如果 捕获 IOError ,抛出 CustomIOError 并处理 CustomIOError 就是您想要的。您可以在 IOError 块

之外使用 try...except 块

一旦异常被 except 子句捕获,同一块中的任何后续异常都将被忽略,因此您不能这样做:

try:
   ...
except Something:
   raise MyError
except MyError: <-- won't work!
  ....

你需要另一个 try 块围绕整个事情:

try:

    try:
       ...
    except Something:
       raise MyError

except MyError: <-- will work
   ...

对于第二个问题,它反过来工作:

try:
  raise CustomIOError
except IOError: <-- works
  pass

这是因为CustomIOErrorIOError,但IOError不是CustomIOError(比较:狗是动物,但(任何)动物不是狗),所以你的例外不匹配。

一般来说,自定义异常提供了一种将一般错误包装到应用程序特定错误中的方法,这样当出现问题时,高级代码就不必处理所有错误细节。例如,您有一个读取文件并将内容写入 sql 数据库的函数。调用此函数的代码只想知道它是成功还是失败,细节无关紧要(尽管它们应该被记录下来以供稍后调查)。因此,该函数仅抛出一个异常以表明它失败了:

# higher-level code

class UserInterface:

     def writeButtonClick:
        try:
            readAndWrite()
        except ReadAndWriteFailure:
            showMessage("Problem! Please try again") 

# lower-level code

class ReadAndWriteFailure(Exception):
    pass

def readAndWrite():
   try:
       fp = open(someFile)
       db = sql.connection()
       for line in fp:
          db.execute(line)
   except IOError:
      log it
      raise ReadAndWriteFailure()
   except SQLError:
      log it
      raise ReadAndWriteFailure()
   etc