可以在Python中引发一个先前实例化的异常吗?

时间:2018-09-02 00:07:20

标签: python exception

我有一个异常类,并且不断用相同的消息提出。这就是我目前的结构方式...

class MyException(Exception):
  UNAUTHORIZED = 'UNAUTHORIZED'
  SOME_OTHER_EXCEPTION = 'SOME_OTHER_EXCEPTION'
  SOME_OTHER_THING = 'SOME_OTHER_THING'
  # ...

def func():
  # ...
  raise MyException(MyException.UNAUTHORIZED)

那是非常不Python的。我想知道我是否可以做这样的事情……

class MyException(Exception):
  UNAUTHORIZED = MyException('UNAUTHORIZED')
  SOME_OTHER_EXCEPTION = MyException('SOME_OTHER_EXCEPTION')
  SOME_OTHER_THING = MyException('SOME_OTHER_THING')
  # ...

def func():
  # ...
  raise MyException.UNAUTHORIZED

...看起来更干净。

我想知道这样做是否可以...在实例化异常的地方是否有任何重要性?

还是我不正确地对待整个事情?我应该做这样的事情吗?

class MyException(Exception):
  pass

class UnauthorizedException(MyException):
  def __init__(self):
    super(UnauthorizedException, self).__init__('UNAUTHORIZED')

def func():
  # ...
  raise UnauthorizedException()

(在这种情况下,我将有大约10个不同的自定义异常类,我认为这有点多,这就是为什么我倾向于我以前的想法的原因。)

1 个答案:

答案 0 :(得分:3)

在Python 3中,异常具有__traceback__属性,该属性存储相应的回溯。如果您在各处重复使用相同的异常对象,那将覆盖__traceback__并造成回溯检查混乱。

此外,重用异常还会使异常链接混乱:__context____cause__。您很可能会看到错误的异常报告为上下文或重用异常的原因。


不要重用异常对象。您应该使用子类,而不要使用raise MyException(MyException.UNAUTHORIZED)raise MyException.UNAUTHORIZED。这样做容易得多

except UnauthorizedException:
    ...

比实际要做的

except MyException as e:
    if e.args != (MyException.UNAUTHORIZED,):
        raise
    ...