【问题标题】:How to handle a custom exception raised inside an exception handler?如何处理异常处理程序中引发的自定义异常?
【发布时间】:2015-03-17 09:05:15
【问题描述】:

如果我运行以下 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支持多态,为什么我不能直接处理基类的异常,用派生类的异常处理程序?

try:
  raise IOError
except CustomIOError:
  pass

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

【问题讨论】:

  • 如果你 raise CustomIOError 你应该 except CustomIOError

标签: python polymorphism


【解决方案1】:

一旦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(比较:狗是动物,但(任何)动物不是狗),所以你的 except 不匹配.

一般来说,自定义异常提供了一种将通用错误包装到特定于应用程序的错误的方法,这样高级代码就不必在出现问题时处理所有错误细节。例如,您有一个读取文件并将内容写入 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

【讨论】:

  • @Marcus:我并不完全清楚你为什么首先需要这个,你能否向我们展示一个更大的图景 - 你的程序做什么,为什么你需要一个自定义异常等?跨度>
  • 恐怕还没有大局。我刚刚开始构建一个库,并且在某些部分我决定使用 python(第一次),我正在尝试这个,因为我发现它很有趣。事实上,我也想知道我什么时候应该真正使用自定义异常,所以如果你能分享一些建议,那将非常有帮助。谢谢。
  • @Marcus:添加了一些解释和示例。
【解决方案2】:
  1. 期望子类型不能捕获超类型错误
  2. A 部分以外的异常抛出的异常不能被 A 旁边的异常部分捕获

所以如果 catch IOError ,抛出 CustomIOError 并处理 CustomIOError 就是你想要的。您可以在 IOError 块之外使用 try...except 块

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-07
    • 2014-06-06
    • 2022-08-09
    • 2015-12-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-13
    相关资源
    最近更新 更多