你在Python中实现自己的Exception吗?

时间:2017-05-04 01:46:05

标签: python exception

你在python中实现自己的异常类吗?
就目前而言,我没有遇到过我遇到麻烦的情况 没有原创的。我的意思是,内置的Exception就足够了。

自我实施的例外的主要好处是什么?

4 个答案:

答案 0 :(得分:5)

通常,您应该定义自己的异常的唯一情况是,当您遇到特定情况时,提出自定义异常比提出现有Python异常更合适。

例如,假设我正在实现解析API的命令行参数,我需要考虑用户输入无效命令行参数的情况,无论它是什么。现在我可以简单地引发一个像SyntaxErrorNameError这样的Python异常,但那将是一个糟糕的设计决定。

我希望能够向用户传达为什么引发异常,而不仅仅是引发异常。更好的选择是子类化常规异常类Exception,并创建特定的自定义异常。也许是InvalidCommandLineArgument

现在我可以使用自定义异常,而不必使用常规Python异常,这有助于清楚简明地告知用户他们的错误。

如果您希望在代码中某个操作失败时收到通知,这也很有用。例如,如果您创建一个从Internet下载certian文件的函数,它可能会引发NoInternetConnection异常,以便在互联网连接断开时通知您。这允许您根据引发的异常采取某种行动。

现在您可能想知道为什么在第二种情况下,如果在尝试使用之前存在互联网连接,则无法使用条件语句 test 。你选择后者与前者的原因是因为Python的座右铭是“请求宽恕比要求许可更容易。”#34;这基本上意味着,如果抛出异常,请求Python更容易捕获异常,而不是尝试使用条件语句来解决所有可能的错误。

最后,它不是关于" 你在Python中实现自己的例外吗?",但" 时你在Python中实现自己的异常?"

答案 1 :(得分:4)

如果您希望将信息传达给致电您代码的其他人,以便他们能够弄清楚该怎么做,最好使用海关例外。

例如:

我们说我写了一个模块pet_store,它提供了一个get_dog(type)函数并且你调用了它。

当我编写函数时,可能会有某些方法可能会失败:

NoDogsLeftException  # Sold out of all dogs
NoDogsOfBreedException  # Sold out of that breed
OwnerHouseCheckException  # We checked your house and it's disgusting. Clean up you slob

现在,当您import pet_storepet_store.get_dog("chihuahua")时,我可能会抛出NoDogsOfBreedException ...因为在这种情况下我不知道您想要做什么。

有些人可能想尝试另一种品种,如果只有奇瓦瓦狗会满足你的话,这是不合理的。如果我抛出一个OwnerHouseCheckException,那也没有意义。如果我说你的房子对狗来说太脏了,那么要求一个不同的品种不会改变我的答案。但是有足够的信息可以采取行动。

这是正确的方法:让任何打电话给你的人弄清楚如果发生异常该怎么办

也许你想:

  • 重试
  • 尝试其他查询
  • 向您的用户显示消息
  • 启动新服务器
  • 发射导弹
  • 释放猎犬

重点是:我不知道你的计划中正确的做法是什么。对你而言,正确的事情可能与其他人不同。相反,我会说"这就是出了什么问题,做你想做的事情。"

某些程序可能完全失败而没有互联网访问(暗黑破坏神III),而其他程序可以处理离线(星际争霸)。这些程序对NoInternetException的反应不同。

答案 2 :(得分:3)

如果您想要捕获您所做的特定类型的异常,这将非常有用。你永远不想只捕获“异常”,因为你可能正在捕捉一些你不知道的异常。

答案 3 :(得分:3)

自定义例外可以清楚地区分不同类型的错误。比较

class NumberTooBig(ValueError):
    pass

class NumberTooSmall(ValueError):
    pass

try:
    ...
except NumberTooBig:
    ...
except NumberTooSmall:
    ...

try:
    ...
except ValueError as exc:
    if str(exc) == "too big":
        ...
    elif str(exc) == "too small":
        ...
    else:
        # A different ValueError I don't know how to handle
        raise exc

使用自定义异常,您可以在异常本身的类型中嵌入有关错误的信息,这样可以更轻松地捕获您想要的特定错误,而无需记住重新引发您意外捕获的任何错误。