在Python中如何正确定义异常类层次结构?
我想要能够像内置异常那样抛出异常,你可以选择传递一条消息,或者直接抛出类名(实例会自动创建)。像这样:
raise IndexError
raise IndexError('Something went wrong, bro')
我的代码这样写对吗?
最开始我想的是这样:
class SomeError(Exception):
def __init__(self, *args):
if args:
print ' '.join(args)
class SomeCriticalError(SomeError):
def __init__(self, *args):
super(SomeCriticalError,self).__init__(*args)
print 'This is a critical error, process stopped ...'
sys.exit(1)
class SomeCookiesError(SomeCriticalError):
def __init__(self, *args):
print 'Firefox cookies retrieving failed ..'
super(SomeCookiesError,self).__init__(*args)
但在这种情况下,我必须为每个CmiCriticalError的子类定义__init__()
,我觉得这样不太对(在每个子类中调用super()
感觉很别扭),然后我试了这个:
class SomeError(Exception):
def __init__(self, *args):
if args:
print ' '.join(args)
else:
print self
class SomeCriticalError(SomeError):
def __init__(self, *args):
super(SomeCriticalError,self).__init__(*args)
print 'This is a critical error, process stopped ...'
sys.exit(1)
class SomeCookiesError(SomeCriticalError):
def __str__(self):
return 'Firefox cookies retrieving failed ..'
但这仍然让我觉得不太对劲,我漏掉了什么吗?
其实我想做的是在异常实例内部处理异常,就像SomeCriticalError
中的sys.exit()
那样,因为在我的主代码中,我可能会在多个地方抛出SomeCookiesError
,我不想每次都传递相同的消息字符串参数,所以我能不能像内置异常那样做?(当没有传递参数时,打印默认消息)
1 个回答
1
一般来说,一个Exception
(异常)子类并不负责处理导致它被抛出的错误。这部分工作是由错误处理代码来完成的,比如用try
/catch
语句包裹住抛出异常的地方。异常类型应该主要负责提供一个友好的提示信息,并封装一些相关的数据。
所以,在你的例子中,处理“严重”错误的方法就是不去捕捉它们(或者只在最顶层捕捉,之后再退出程序)。很多异常类可以很简单:
class SomeCriticalError(Exception):
pass
一些其他的异常类可能会做得多一些,但它们应该专注于记录情况的相关细节,而不是解决问题的方法:
class CookieError(Exception):
def __init__(self, cookie_name):
super(CookiesError, self).__init__("Could not find Firefox cookie {!r}"
.format(cookie_name)) # custom message
如果你在调试CookieError
时需要一些额外的数据,你可以让你的异常类把这些数据保存到self.data
或者其他地方(不过如果你想让raise CookieError
的语法正常工作,你需要把__init__
方法的所有参数设为可选)。