2017-05-04 36 views
0

你在python中实现自己的异常类吗?
现在,我还没有遇到过我麻烦
没有得到原有的局面。我的意思是,内置的Exception就足够了。你在Python中实现自己的异常吗?

自我实现异常的主要好处是什么?

+0

与大多数语言不同,Python中的异常相对便宜,并且经常用作荣耀的GOTO--常常使用自定义异常来进行流量控制。 –

+0

有趣......“用于流量控制”意味着自定义异常有时用于非特殊情况? – Pythoner

+0

是的。最好的例子是'for'循环:当迭代器耗尽时,它会引发StopIteration。这根本不是特例,迭代器协议是该语言的核心。 –

回答

3

一般来说,你应该定义自己的异常的唯一时间是当你有一个特定的情况下提出一个自定义异常会比养现有Python异常更为合适。

例如,说我正在执行的命令行参数解析API,我需要以考虑其中用户输入了一个无效的命令行参数,不管它可能是这种情况。现在,我可以简单提高Python异常像SyntaxErrorNameError,但是这将是一个糟糕的设计决策。

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

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

,如果你想在某个动作在你的代码没有被告知这也可以是有用的。例如,如果您创建了一个从互联网下载certian文件的功能,它可能会引发异常,以便在互联网连接关闭时通知您。这使您可以根据引发的异常情况采取特定的操作。

现在你可能想知道为什么在第二种情况下,你不能简单地使用条件语句来测试是否有尝试使用它之前的互联网连接。你选择后者与前者的原因是因为Python的座右铭是“请求宽恕比请求许可更容易。”这基本上意味着,如果抛出异常,那么请求Python捕获异常比使用条件语句试图绕过所有可能的错误更容易。

最后,它不是关于“你在Python中实现自己的异常?”,而是“你在Python中实现自己的异常?”

+0

非常感谢。现在我懂了。我们必须向用户传达为什么会引发异常,并且有时会根据异常的种类采取某种行动。另外,我在脑海中记住了这一点,“要求宽恕比要求许可容易”。 – Pythoner

+0

我很高兴能帮助你更好地理解,@Daichi。您可能还有兴趣阅读[官方Python文档]中有关例外的更多信息。(https://docs.python.org/3/library/exceptions.html) –

1

如果您想要捕捉您制定的特定类型的例外情况,这很有用。你永远不想只抓住“例外”,因为你可能会捕捉到你不了解的其他异常。

+0

虽然我明白你想说什么,但我不认为你说得很好。你没有使用基本异常类的权利。你可能会掩盖重要的错误。 _但是,你也不应该只是创建你自己的例外。如果Python已经提出错误,那么您也尝试创建自己的错误也没有意义。这是多余的。相反,找出您的代码可能引发的确切错误,然后解释这些具体的错误。 –

+0

我在想更多,这是避免意外错误导致代码中出现错误的好方法。例如,如果您的代码引发了ValueError并将其捕获到别的地方,那么您可能会错过其他某个库引发自己的ValueError的另一个地方。当然 - 在一个理想的世界中,你不会写出抛出错误的代码,但它不是一个理想的世界。 – Arya

1

自定义异常可以明确区分不同类型的错误。比较

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 

有了自定义异常,您嵌入有关异常本身,这使得它更容易捕捉只有你想要的特定错误,而不必记住类型的错误信息重新提出您意外抓到的任何错误。

+0

感谢您展示具体的例子! – Pythoner

2

当您想将信息传递给调用您的代码的其他人时,最好使用海关例外,以便他们可以确定要执行的操作。

例如:

比方说,我写了一个模块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会有不同的反应。

+0

该列表对我来说非常有帮助(而且很有趣)!谢谢。我总是只显示一条消息。现在我可以根据情况做更多的事情。 – Pythoner

相关问题