【问题标题】:Catching multiple exceptions and passing to custom Exception handler using Python使用 Python 捕获多个异常并传递给自定义异常处理程序
【发布时间】:2014-06-10 18:52:10
【问题描述】:

我正在使用 imapclient 模块编写一些 python 代码,并想捕捉它的异常并向它们添加一些消息。我知道模块有以下异常:socket.error、socket.gaierror、IMAP4.error、IMAP4.abort、IMAP4.readonly

首先,人们是否通常将自定义异常放在单独的模块中并导入它们,以保持代码清晰和干净?如果没有,为什么不呢?

其次,知道这个模块有什么异常,我不确定如何捕获所有异常,然后破译捕获到哪个异常并使用自定义异常类适当地处理它。允许我添加其他消息或我可能想做的任何事情。

第三,我是否有一个“MyException”类,它可以为我可能期望和传入的五个异常中的每一个具有不同的逻辑?

我的第一次糟糕的尝试:

def some_func():
    try:
        login(email, password)
        print "logged into account as: %s " %email
    except Exception, e:
        raise MyException, e

class MyException(Exception):
    if Exception == socket.error:
        print 'Additional messaging here'
    elif Exception == something.else:
        do this

【问题讨论】:

  • 你的问题有点不清楚。你打算MyException里面的代码做什么?
  • 对不起,我是初学者。和我在一起,我试图将捕获的异常传递给 MyException 类。然后我的异常处理程序将确定我期望的五个异常中的哪一个,并向其中添加一些打印语句。
  • 我在下面给出了答案。为什么要捕获所有异常然后将它们传递给 MyException?通常最好捕获特定异常,然后在必要时为每个异常引发自定义异常。
  • 除了我不知道最佳实践/什么是有意义的并尝试学习之外,没有什么特别的原因。谢谢你的回答!

标签: python exception


【解决方案1】:

假设您真的想要这样做,您通常会在引发异常的地方检查您的各种条件,并使用该信息引发正确的异常。大致:

# base class for your custom exceptions
class MyException(Exception):
    pass

# class to wrap socket error
class MySocketException(MyException):
    pass

# class for some other exception
class MyOtherException(MyException):
    pass

def some_func():
    try:
        login(email, password)
        print "logged into account as: %s " %email
    except socket.error:
        raise MySocketException, "My custom socket error message"
    except SomeOtherException:
        raise MyOtherException, "My custom error message"

这解决了您关于“捕获所有这些并破译哪个”的问题。这样做的方法是使用多个except 子句,一个用于您想要一起处理的每种异常(或一组异常)。然后,在每个 except 子句中,执行您想要执行的操作来处理这些异常。这比将它们全部放在一个大的except 子句中并稍后尝试将它们分开要好。使用except 的部分意义在于它可以让您指定要捕获的异常类型。

但是,您应该考虑一下为什么要这样做。用只替换一种错误的自定义异常类替换像socket.error 这样的普通异常并没有多大用处。在这种情况下,为什么不直接捕获并处理socket.error?您通常会为特定于您的程序的各种错误创建异常类。

关于人们是否将异常放在单独的模块中的问题,这取决于您。通常,当将它们全部放在同一个模块中变得笨拙时,您应该将它们拆分为单独的模块。如果您的模块很小并且只定义了几个 Exception 类,那么通常不需要为它们制作单独的模块。如果模块很大并且具有复杂的异常层次结构,您可能希望将它们拆分为单独的模块。

【讨论】:

    【解决方案2】:

    首先,人们通常是否将自定义异常放在单独的 模块并导入它们,以保持代码清晰和干净?如果没有,为什么不呢?

    视情况而定。通常,如果自定义异常类型与当前模块中的代码密切相关(通常是这样),那么在此处定义它是最有意义的。

    第二,知道这个模块有什么异常,我不知道 完全确定如何抓住所有这些,然后破译哪个 异常被捕获并使用自定义适当地处理它 异常类。

    您不需要自定义异常类。像这样的东西会起作用:

    try:
        ...
    except (Exception1, Exception2, Exception3) as e:
        if isinstance(e, ...):
            do_this()
        elif isinstance(e, ...):
            do_that()
        else:
            do_something_else()
    

    当然,您可以使用自定义错误类型进一步抽象它,但您没有解释为什么需要它们。

    第三,我是否有一个“MyException”类可以有不同的 我可能期望的五个例外中的每一个的逻辑 并传入?

    这取决于。我仍然不相信您需要自定义错误类。如果是关于共享代码,您可以轻松编写

    try:
        ...
    except (Exception1, Exception2, Exception3) as e:
        handle_exception(e)
    

    然后只需定义一个有用的函数handle_exception(e) 并从不同的地方调用它。

    【讨论】:

    • 捕获三种异常,然后用isinstance 拆分出来比较尴尬。相反,只需三个单独的 except 子句,每个子句捕获一种类型,并在不同的 except 子句中包含 do_thisdo_that
    • @BrenBarn 捕获异常元组是“我不确定如何捕获所有异常”的最短方法。在示例中,我只是提供想法...
    • @Jan-Philip Gehrcke 感谢您直接回答我的每一个问题。我接受另一个只是因为它是第一个并且帮助了我。
    • 没关系 :) 但如果答案有帮助,点赞也无妨:)
    猜你喜欢
    • 2018-05-30
    • 1970-01-01
    • 2013-05-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-05-02
    • 2018-09-24
    相关资源
    最近更新 更多