python Exceptions作为类属性是一件坏事吗?

Jes*_*ame 7 python exception

我发现自己经常想要构建我的异常类,如下所示:

# legends.py
class Error(Exception): pass

class Rick(object):
    class Error(Error): pass
    class GaveYouUp(Error): pass
    class LetYouDown(Error): pass

class Michael(object):
    class Error(Error): pass
    class BlamedItOnTheSunshine(Error): pass
    class BlamedItOnTheMoonlight(Error): pass
Run Code Online (Sandbox Code Playgroud)

我只看到了Django(DoesNotExist)中使用的这种模式,它非常有意义.有什么我想念的,为什么大多数人似乎都喜欢顶级的例外?

编辑 我会将这些类用于多种粒度,例如:

import legends

try:
    do_stuff()
except legends.Michael.Error:
    blame_it_on_the_boogie()
except legends.Rick.GaveYouUp:
    let_you_down()
except legends.Error:
    pass
except Exception as e:
    raise Hell()
Run Code Online (Sandbox Code Playgroud)

Mar*_*cin 9

这是Django用于某些与ORM相关的异常的确切模式.

优点是你可以有一个except子句来检查通过实例访问的类型:

rick = Rick()

try:
   rick.roll()
except rick.GaveYouUp:
   never()
except rick.LetYouDown:
   never_ever()
Run Code Online (Sandbox Code Playgroud)

这看起来不太有用,但如果rick是函数参数,那么它可能会非常有用.

这在编写引发异常的通用代码时非常有用:

GoddamStar(object):
   def sing(self,tune):
       raise self.Error()

class Rick(GoddamStar):
    class Error(Error): pass
    class GaveYouUp(Error): pass
    class LetYouDown(Error): pass

class Michael(GoddamStar):
    class Error(Error): pass
    class BlamedItOnTheSunshine(Error): pass
    class BlamedItOnTheMoonlight(Error): pass

rick = Rick()

try:
   rick.sing()
except Rick.GaveYouUp:
   never()
except Michael.Error:
   never_ever()
Run Code Online (Sandbox Code Playgroud)

Django的例外通常都是从全局基类派生的,因此你也可以拥有一个catch-all子句,如果你rick是一个未知的(或其他未提供的)类,它仍然会打开一种异常类型.

这不是更常见的原因是:(a)它不适用于早期约束语言,它吸引了大多数书籍作者(b)这对于用户来说很有用,因此适用作家可能认为他们不需要它.