我想要一个类似自定义错误代码/消息数据库的东西,并在引发异常时使用它(在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?

最佳答案

当然。异常类只是普通类,因此您可以定义自己的__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)的原因。



如果确实要使用错误代码,则可能要考虑使用Enumone of the fancier enum types on PyPI,它们可以更轻松地将自定义字符串附加到每个字符串。



您几乎永远都不希望从BaseException继承,除非您专门尝试确保不会捕获到异常。

关于python - Python 3.4中的自定义异常代码和消息,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/25004491/

10-14 17:15
查看更多