Python 3.4中的自定义异常代码和消息
我想要创建一个自定义的错误代码和消息数据库,然后在抛出异常时使用它(在Python 3.4中)。于是我做了以下的事情:
class RecipeError(Exception):
# Custom error codes
ERRBADFLAVORMIX = 1
ERRNOINGREDIENTS = ERRBADFLAVORMIX + 1
# Custom messages
ERRMSG = {ERRBADFLAVORMIX: "Bad flavor mix",
ERRNOINGREDIENTS: "No ingredients to mix"}
raise RecipeError(RecipeError.ERRMSG[RecipeError.ERRBADFLAVORMIX])
这样做的效果是我预期的,但这个raise
语句看起来实在太复杂了。当然,我可以用更简洁的方式来存储这些值,但我真正想知道的是:我能不能直接用raise RecipeError(code)
,然后让RecipeError自己去处理获取消息的工作呢?
1 个回答
3
当然可以。异常类其实就是普通的类,所以你可以定义自己的 __init__
方法,并适当地调用 super
。
class RecipeError(BaseException):
# existing stuff
def __init__(self, code):
super().__init__(self, RecipeError.ERRMSG[code])
你可能还想保存这段代码:
class RecipeError(BaseException):
# existing stuff
def __init__(self, code):
msg = RecipeError.ERRMSG[code]
super().__init__(self, msg)
self.code, self.msg = code, msg
可以看看标准库中的异常信息(在3.4版本中相当不错,虽然以后还会有更多变化……),了解一下哪些信息可能对你有用。
一些附带说明:
首先,使用子类可能比使用错误代码更好。例如,如果有人想写代码来捕捉 ERRBADFLAVORMIX
这个错误,但不想捕捉 ERRNOINGREDIENTS
,他们需要这样做:
try:
follow_recipe()
except RecipeError as e:
if e != RecipeError.ERRBADFLAVORMIX:
raise
print('Bad flavor, bad!')
而如果你使用了子类的话:
try:
follow_recipe():
except BadFlavorRecipeError as e:
print('Bad flavor, bad!')
这正是为什么Python不再有一个庞大的 OSError
和一个需要你去判断的 errno
值,而是有像 FileNotFoundError
这样的独立子类。
如果你确实想使用错误代码,可能可以考虑使用 Enum
,或者在PyPI上找一些更高级的枚举类型,这样可以更方便地为每个错误附加自定义字符串。
你几乎不想从 BaseException
继承,除非你特别想确保你的异常不会被捕捉到。