《Python基础教程》第八章--读书笔记 - michael翔的IT私房菜
第八章:异常
python的异常对象提供了非常强大的替代方案。
什么是异常
python用异常对象(ecxeption object)来表示异常情况。遇到错误之后,会引发异常。如果异常对象并未被处理或捕捉,程序就会用所谓的回溯(traceback,一种错误信息)终止执行。
事实上,每个异常都是一些类的实例,这些实例可以被引发,并且可以用很多方法进行捕捉,使得程序可以捉住错误并且对其进行处理,而不是让整个程序失效。
按自己的方式出错
如何引发异常,以及创建自己的异常类型。
raise语句
为了引发异常,可以使用一个类(应该是Exception的子类)或者实例参数调用raise
语句。使用类时,程序会自动创建类的一个实例。
>>>raise Exception---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-67-fca2ab0ca76b> in <module>()----> 1 raise Exception Exception: >>>raise Exception('hyperdrive overload')---------------------------------------------------------------------------Exception Traceback (most recent call last)<ipython-input-68-b31edcf659a9> in <module>()----> 1 raise Exception('hyperdrive overload') Exception: hyperdrive overload
第二个例子引发了错误,并且添加了错误信息。
内建的异常类有很多。python库参考手册的built-in exceptions
一节中有关于它们的描述。用交互式解释器可以分析它们,这些内建异常都可以在exceptions
模块(和内建的命名空间)中找到。
下表描述了一些最重要的的内建异常类:
类名 | 描述 |
---|---|
Exception | 所有异常的基类 |
AttributeError | 特性引用或赋值失败时引发 |
IOError | 试图打开不存在文件(包括其他情况)时引发 |
IndexError | 在使用序列中不存在的索引时引发 |
KeyError | 在使用映射中不存在的键时引发 |
NameError | 在找不到名字(变量时)引用 |
SyntaxError | 在代码为错误形式时引发 |
TypeError | 在内建操作或者函数引用于错误类型的对象时引发 |
ValueError | 在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发 |
ZeroDivisinError | 在除法或者模除操作的第二个参数为0时引发 |
自定义异常类
那么如何创建自己的异常类呢?就像其他类一样,只是要确保从Exception
类继承(不管是间接的或者直接的,也就是说继承其他的内建异常类也是可以的)。
class SomeCunstomException(Exception):pass
捕捉异常
关于异常的最有意思的地方就是可以处理它们(通常叫做诱捕异常或捕捉异常)。这个功能使用try/except
语句来实现。
try: x = input("enter a number:") y = input("enter another number:") print x/yexcept ZeroDivisionError: print "the second number can't be zero"
不止一个except子句
利用多个except
子句,可以捕捉不同类型的异常,给出相应的提示,很方便
用一个块捕捉两个异常
相比上面用多个except
捕捉异常,用一个块捕捉异常显得方便点。“眉毛胡子一把抓”。
try: x = input("enter a number:") y = input("enter another number:") print x/yexcept (ZeroDivisionError,TypeError,NameError): print "Your number were bogus……"
注:except
子句中异常对象外面的圆括号很重要。忽略它们是一种常见的错误
捕捉对象
因为某种原因,“眉毛胡子一把抓”时的错误也想打印下来,这个功能就很有用。
try: x = input("enter a number:") y = input("enter another number:") print x/yexcept (ZeroDivisionError,TypeError,NameError),e: print e
在python3中,except
子句会被写作except (ZeroDivisionError,TypeError,NameError) as e:
真正的全捕捉:
try: x = input("enter a number:") y = input("enter another number:") print x/yexcept Exception,e: #也可以直接except:但是,这样的捕捉所有异常时危险的,因为它会隐藏所有程序员未想到并且未做好准备处理的错误。 print "something wrong happened"enter a number:1enter another number:something wrong happened
最后……
最后,是finally
子句。它可以用来在可能的异常后进行清理。它和try
子句联合使用。
finally
子句肯定会被执行,不管是否发生异常。
异常和函数
异常和函数能很自然的在一起工作。如果异常在函数内引发而不被处理,它就会传播至(浮到)函数调用的地方。如果在那里也没有处理异常,它就会继续传播,一直到达主程序(全局作用域)。如果那里没有异常处理程序,程序就会带着栈跟踪终止。
本章小结:
异常处理并不是很复杂。如果知道某段代码可能会导致异常,而又不希望程序以
堆栈跟踪
(没明白)的形式终止,那么就根据需要添加try/except
或者try/finally
语句(或者它们结合)进行处理。else
子句。除了except
子句,可以使用else
子句。如果主try
块中没有引发异常,else
子句就会被执行。
今天看了下《python核心编程》介绍类方面的内容,确实介绍更详细点啊。囧。当时早知道看它好了,不过已经选择了,就把《python基础教程》看完了好了。