如何在Python中捕获自定义异常

16

我正在使用一个Python库,在其中一个地方定义了一个异常,如下:

raise Exception("Key empty")

我现在希望能够捕获那个特定的异常,但我不确定如何做到这一点。

我尝试了以下方法

try:
    raise Exception('Key empty')
except Exception('Key empty'):
    print 'caught the specific exception'
except Exception:
    print 'caught the general exception'

但那只是打印出了caught the general exception

有人知道我如何捕获特定的Key empty异常吗?欢迎提供任何提示!

2个回答

15

定义你的异常:

class KeyEmptyException(Exception):
    def __init__(self, message='Key Empty'):
        # Call the base class constructor with the parameters it needs
        super(KeyEmptyException, self).__init__(message)

使用它:

try:
    raise KeyEmptyException()
except KeyEmptyException as e:
    print e

更新:根据评论中提供的讨论:

  

但这个库不在我的控制之下。它是开源的,所以我可以编辑它,但我最好尝试在不编辑库的情况下捕获它。这不可能吗?

假设库引发异常:

# this try is just for demonstration 
try:

    try:
        # call your library code that can raise `Key empty` Exception
        raise Exception('Key empty')
    except Exception as e:
        # if exception occurs, we will check if its 
        # `Key empty` and raise our own exception
        if str(e) == 'Key empty':
            raise KeyEmptyException()
        else:
            # else raise the same exception
            raise e
except Exception as e:
    # we will finally check what exception we are getting
    print('Caught Exception', e)

1
但是这个库不在我的控制范围内。它是开源的,所以我可以编辑它,但最好不要编辑库来尝试捕捉异常。这不可能吗? - kramer65
我甚至会选择RuntimeError作为基类。 - Gribouillis
如果由库引发的异常得到了修复,那么你必须捕获该异常。你可以捕获该异常并抛出自己的异常作为替代。 - Vikash Singh

3

你需要继承 Exception 类:

class EmptyKeyError(Exception):
    pass

try:
    raise EmptyKeyError('Key empty')
except EmptyKeyError as exc:
    print(exc)
except Exception:
    print('caught the general exception')

1
为什么我们需要子类化异常? - ampersand
@ampersand 可能会有所帮助:https://docs.python.org/3/library/exceptions.html 和 https://docs.python.org/3/tutorial/errors.html#tut-userexceptions。 - hiro protagonist
1
你从Exception派生的方式比被接受答案中的方式要简短得多。对我来说,你的版本在捕获异常时似乎绰绰有余。你同意在这里编写自己的__init__除了增加噪音之外什么也没有做吗? - Wolf
@Wolf 这有点取决于你的目标是什么。但在这种情况下:我同意! - hiro protagonist
1
感谢您的光临。对我来说,为了分类(和层次化)错误,pass实现将是一个不错的选择。当异常类中存在其他需要初始化的字段时,自定义构造函数当然是必需的。 - Wolf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接