Python文档states:
异常通常应该从Exception类派生, 直接或间接地。
'typically'
这个词使我处于模棱两可的状态。
考虑代码:
class good(Exception): pass
class bad(object): pass
Heaven = good()
Hell = bad()
>>> raise Heaven
Traceback (most recent call last):
File "<pyshell#163>", line 1, in <module>
raise Heaven
good
>>> raise Hell
Traceback (most recent call last):
File "<pyshell#171>", line 1, in <module>
raise Hell
TypeError: exceptions must be classes or instances, not bad
所以在阅读python文档时,我应该用'typically'
替换''
吗?
如果我有一个与Exception类无关的类层次结构,并且我想“提升”属于该层次结构的对象,该怎么办?
我总是可以使用参数引发异常:
raise Exception, Hell
这对我来说似乎有些尴尬
Exception(EDIT:或BaseException)类有什么特别之处,只能提升其家庭成员?
答案 0 :(得分:21)
除了Exception
之外,您还可以继承其他有效的类,例如BaseException
。
请参阅exception hierarchy的文档。
BaseException
+-- SystemExit
+-- KeyboardInterrupt
+-- GeneratorExit
+-- Exception
+-- StopIteration
+-- StandardError
etc..
在旧版本的Python中,可以抛出异常以外的东西。例如在Python 2.5中:
>>> raise "foo"
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
foo
但是你得到了这个弃用警告:
DeprecationWarning: raising a string exception is deprecated
在较新的版本中,这是不允许的。你提出的所有内容都必须来自BaseException。
答案 1 :(得分:9)
“所以在阅读python文档时, 我应该用''改变'''吗?
没有
通常,您从Exception继承。期。这就是它所说的。
有时,您可能会继承BaseException。这就是它没有说的。您可以扩展BaseExcetion,因为您想要击败except Exception
处理程序。
有什么特别的......
他们是BaseException
的子类。你还需要知道什么?来源随时可用。您可以阅读raise
语句的源代码,以便在它抛出TypeError
之前确切地查看它所检查的内容。
http://svn.python.org/view/python/trunk/Python/ceval.c?annotate=80817
第3456至3563行。
然而,从实际角度来看,重要的是“BaseException
的子类。”
答案 2 :(得分:3)
'通常'是因为有一些非常罕见的异常类型不希望被通用Exception
处理程序捕获。如果有疑问继承自Exception
,但该规则有例外。
大多数异常用于指示由代码和数据导致的某种错误或异常情况。这些异常都是Exception
的子类。如果你想提出自己的异常,它可能属于那个类别,因此也应该继承Exception
。如果你想要一个通用异常处理程序,例如为了记录错误,捕获Exception
并期望以这种方式捕获任何错误是完全合理的。
直接从BaseException
继承的其他例外情况略有不同。当您致电SystemExit
(或者您可以直接提出)时,会引发sys.exit()
。如果您确实有一些记录错误的顶级代码,那么您可能不希望它以相同的方式处理SystemExit
。您曾经必须为SystemExit
包含一个单独的处理程序,以便阻止通用异常处理程序捕获该情况。
KeyboardInterrupt
确实表示意外情况,但它是由用户的外部输入引发的,因此它可以在代码中的任何位置发生;它不以任何方式依赖于代码或数据。这意味着即使您确实想要处理它,您可能希望以不同于继承自Exception
的异常来处理它。
答案 3 :(得分:0)
也可以引发从各种错误/异常类派生的东西,但这些东西通常是为其他东西保留的。
答案 4 :(得分:0)
有时你可能想要提出你不认为是例外的事情(但规则)。对于这些罕见的情况,人们可以认为raise
除了例外之外还有其他的东西。
在一个递归计算中,在某个时刻找到答案,将它提升到向上等待的捕手可以非常整洁(而不是return
这意味着递归必须预期这一点,向上传递它等等。)。
但是现在只有老式的类(出于兼容性原因我猜)和BaseException的派生可以引发,因为有太多的人滥用像字符串这样的异常。