[英]Are python Exceptions as class attributes a bad thing?
我发现自己经常想要构建我的异常类,如下所示:
# 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
我只看到了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()
这是Django用于某些与ORM相关的异常的确切模式。
优点是你可以有一个except子句来检查通过实例访问的类型:
rick = Rick()
try:
rick.roll()
except rick.GaveYouUp:
never()
except rick.LetYouDown:
never_ever()
这看起来并不有用,但如果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()
Django的例外通常都来自全局基类,因此你也可以拥有一个catch-all子句,它仍然可以打开一种异常类型,以防你的rick
是一个未知的(或其他未提供的)类。
这不是更常见的原因是:(a)它不适用于早期约束语言,这吸引了大多数书籍作者(b)这对于用户来说很有用,因此应用程序很有用。作家可能认为他们不需要它。
如果你想在Micheal之外举起例如BlamedItOnTheSunshine你必须通过加注Micheal.BlamedItOnTheSunshine('错误文本')来调用它。
例如:
class A:
class E(Exception): pass
def __init__(self): raise A('error in A')
class B:
def __init__(self): raise A.E('error in B')
在这个例A和B中没有关系,但是如果你有这样的关系:
class Interpret(object):
class LetsYouDown(Exception): pass
def __init__(self): raise self.LetsYouDown("I'm not Rick!")
class Michael(Interpret):
class BlameItOnTheSunshine(Exception): pass
def __init__(self): raise self.BlameItOnTheSunshine("It's not the Moon!")
class Rick(Interpret):
class NeverEver(Exception): pass
def __init__(self): print "Never Ever!"
and want now something like:
try:
for superstar in [Interpret, Michael, Rick]:
star_in_show = superstar()
except superstar.LetsYouDown:
print "Where's Rick?"
except superstar.BlameItOnTheSunshine:
print "Must be Michael!"
你会得到一个错误我会称Liskov的原则违规。 因此,使用OOP的主要原因之一(多态性)有些受到损害。 但它并不意味着你不能或不应该使用它。 请注意这些限制。
我希望清除我最初的密码保留。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.