第八章 异常

来源:互联网 发布:java现在的就业前景 编辑:程序博客网 时间:2024/06/08 00:10

8.1 什么是异常(异常都是立马执行的)

python用异常对象(exception object)表示异常情况。遇到错误后,会引发异常。如果异常对象未被处理或捕捉,程序就会用回溯(traceback,一种错误信息)终止执行。每个异常都是一些类的实例

8.2  按自己方式出错

8.2.1    raise

使用一个类(Exception的子类)或实例参数调用raise

 捕捉异常并且进行处理,而不让整个程序崩溃

>>> raise ExceptionTraceback (most recent call last):  File "<pyshell#0>", line 1, in <module>    raise ExceptionException>>> raise Exception("hyperdrive overload")#添加错误信息Traceback (most recent call last):  File "<pyshell#1>", line 1, in <module>    raise Exception("hyperdrive overload")#添加错误信息Exception: hyperdrive overload

可以添加错误信息
可以使用dir(exceptions)  列出内建异常 

表8-1描述了一些最重要的内建异常类:

表8-1 一些内建异常类

 

Exception            所有异常的基类

AttributeError           特性引用或赋值失败时引发

IOError             试图打开不存在文件(包括其他情况)时引发

IndexError                                         在使用序列中不存在的索引时引发

KeyError              在使用映射中不存在的键时引发

NameError             在找不到名字(变量)时引发

SyntaxError            在代码为错误形式时引发

TypeError             在内建操作或者函数应用于错误类型的对象时引发

ValueError            在内建操作或者函数应用于正确类型的对象,但是该对象使用不合适的值时引发

ZeroDivisionError         在除法或者模除操作的第二个参数为0时引发


8.2.2 自定义异常类型

      为什么要自定义?
可以根据异常所在的类,选择性地处理当前类型的异常。所以如果想要用特殊的错误处理代码处理错误,就要自定义一个异常类。
如何创建?
确保自
定义类是从Exception类继承的(直接或者间接)

class SomeCustomException(Exception): pass


8.3    捕捉异常(处理异常)
重点   使用.    try....except
Enter the first number: 10Enter the second number: 0Traceback (most recent call last):  File "/home/marlowes/MyPython/My_Exception.py", line 6, in <module>    print x / yZeroDivisionError: integer division or modulo by zero

使用try.....except
try:    x = input("Enter the first number: ")    y = input("Enter the second number: ")    print x / yexcept ZeroDivisionError:    print "The second number can't be zero!"
让错误发生时,执行别的语句
比if要好,因为只要写一个错误处理器.

注:如果没有捕捉异常,它就会被“传播”到调用的函数中。如果在那里依然没有捕获,这些异常就会“浮”到程序的最顶层,也就是说你可以捕捉到在其他人的函数中所引发的异常。有关这方面的更多信息,请参见8.10节。    8.10(看不懂,之后再来看

异常的抛出机制:

1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler.

2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。

3、如果在最外层(全局“main”)还是没有找到的话,程序会带着栈跟踪终止,同时打印出traceback以便让用户找到错误产生的原因。

 

>>> def faulty():...     raise Exception("Something is wrong")... >>> def ignore_exception():...     faulty()... >>> def handle_exception():...     try:...         faulty()...     except:...         print "Exception handled"... >>> ignore_exception()Traceback (most recent call last):  File "<stdin>", line 1, in <module>  File "<stdin>", line 2, in ignore_exception  File "<stdin>", line 2, in faultyException: Something is wrong>>> handle_exception()Exception handled
可以看到,faulty中产生的异常通过faulty->ingore_exception传播,最终导致栈跟踪,handle_exception同理


如果捕捉到了异常,但是又想重新引发它(也就是说要传递异常,不进行处理),那么可以调用不带参数的raise(还能在捕捉到异常时显式地提供具体异常,在8.6节会对此进行解释)。          重新把异常继续向上传递。


作用:举个例子吧,看看这么做多么有用:考虑一下一个能“屏蔽”ZeroDivisionError(除零错误)的计算器类。如果这个行为被激活,那么计算器就打印错误信息,而不是让异常传播(说明没except异常)。如果在与用户交互的过程中使用,那么这就有用了,但是如果是在程序内部使用,引发异常会更好些。因此“屏蔽”机制就可以关掉了,下面是这样一个类的代码:

class MuffledCalculator():        muffled = False #默认关闭屏蔽        def calc(self, expr):        try:            return eval(expr)        except ZeroDivisionError:            if self.muffled:                print "Division by zero is illegal"#打开屏蔽,用户交互时使用            else:                raise   #关闭屏蔽


注:如果除零行为发生而屏蔽机制被打开,那么calc方法会(隐式地)返回None。换句话说,如果打开了屏蔽机制,那么就不应该依赖返回值。

8.4 使用多个except

1.使用多个子句

2.使用元组包含多个异常类型


8.6 捕捉对象

在except子句中访问异常对象本身

 显示的捕捉对象本身

下面的示例程序会打印异常(如果发生的话),但是程序会继续运行:

try:    x = input("Enter the first number: ")    y = input("Enter the second number: ")    print x / yexcept (ZeroDivisionError, TypeError), e:#as e     在python3.0中    print e

8.7 全捕捉

直接使用 except:    (不加入错误类型),捕捉所有异常

危险

可以使用 except Exception,e:      会更好,这样可以对e做一些检查

8.8 else

没出现错误时,执行else

8.9 finally

不管异常是否发生,都执行

通常用来清理

x = Nonetry:    x = 1 / 0finally:    print "Cleaning up..."    del x

在程序traceback之前,清理就已经完成。

0 0