Python基础——异常

来源:互联网 发布:佳能打印机软件下载 编辑:程序博客网 时间:2024/06/05 08:41

      • 异常类型
        • 内置异常类型
        • 用户自定义异常类
      • 异常触发方式
        • 自动触发
        • 手动触发
      • 异常处理
        • 默认处理器
        • try处理器
      • 异常不仅仅是错误
      • 其他

python提供了异常处理机制。在默认情况下,如果程序中出现异常,python会打印出错消息,这是python默认的异常处理器。除此之外,python还允许用户自行捕获并按自己的需求处理异常。本文将从异常数据类型、异常触发方式、异常的捕获及处理三个方面进行介绍。


异常类型

异常是通过类实现的。

内置异常类型

  • BaseException

  • Exception
    是所有其他内置异常的超类,除了系统退出事件类之外,比如SystemExit, KeyboardInterrupt, GeneratorExit。

  • ArithmeticError
    所有数值错误的超类。

用户自定义异常类

一般需要继承自BaseException或者Exception:

class MyException(BaseException):pass



异常打印

传递给异常类构造函数的所有参数都会保存在args元组中,并且在打印该实例的时候自动显示,另外在由默认异常处理器处理异常时,该数据也会作为消息的一部分:

>>> I = IndexError('datadata')>>> I.args('datadata',)>>> print I  datadata>>> raise IndexError('datadatadata', 'hhhhhh')Traceback (most recent call last):  File "<stdin>", line 1, in <module>IndexError: ('datadatadata', 'hhhhhh')

异常虽然不是字符串对象,但在打印的时候会调用str运算符重载协议来打印成字符串;通过修改str可以定制打印:

class MyBad(Exception):    def __str__(self):        return 'string wanted to print'

这样在异常实例被打印或者异常到达默认处理器时,会打印__str__方法返回的字符串。

为异常提供数据和方法
可以通过定制的构造函数为异常实例提供额外的数据属性,还可以增加额外的函数:

class MyException(Exception):    logfile = '**.txt'    def __init__(self, line, file):        self.line = line        self.file = file    def logerr(self):        log = open(self.logfile, 'a')           print >> log  'error at', self.file, self.line

可以通过异常对象调用这些额外的数据属性值或者方法。


异常触发方式

自动触发

由程序自动触发。

手动触发

  • raise语句
raise Exception #隐式调用构造函数raise Exception() #显式调用构造函数raise Exception(args) #通过传递参数显式调用构造函数raise #触发最近的异常,常用于异常处理器中,以传播已捕获的异常

raise触发的异常必须是类的一个实例。raise语句会把异常类型和实例一起发送,except exception as data语句和这一概念相关,data会引用raise传递的实例对象。

  • assert语句
    assert语句可以看成是含有if判断的raise语句的替代物:
assert expression , data#data是可选的,在异常没有被捕捉到时,data会做为出错消息的一部分if not expression:    raise exception

异常处理

默认处理器

当有异常被触发,而没有try语句捕获时,会调用python的默认异常处理器:打印标准出错消息。消息包含了个堆栈跟踪Traceback以及异常的名称和细节。

try处理器

try语句的语法:

try:    程序except exception1:    ...except (exception1, exception2):    ...except exception as data:#捕获的exception类型的异常实例赋值给data,这样可以使用异常实例的属性    ...except: #所有其他类型的异常    ...else:    ...finally:    ... 

try语句必须有一个except或者finally;可以有多个except子句;如果有else,那么必须至少有一个except;可以只有finally。
try语句是可以嵌套的。

excep:...子句会引发一些问题:也会捕捉到系统退出、内存耗尽、键盘中断等异常,但是实际上我们会希望忽略这些异常。
except Exception:...可以用来解决这一问题。

try/except/else

try:    fun()except MyException:    print "error"else:    print "no error"        

在上面的代码中,在执行try中的主要程序时:

  • 触发异常,首先捕捉该异常
    如果有匹配项(异常是某个exception或者是其子类),表示该异常被try/except**捕捉**到,那么执行该匹配except分支中的语句,并从异常中恢复,此时异常die;否则,表示该异常没有被try语句捕捉到,那么把异常向上层传递,比如这里会把异常传给python的默认异常处理器,打印出错消息,并且终止程序。

  • 没有触发异常,那么会执行else语句。

try/finally

try:    fun()finally:    close   

上面的代码中,无论主代码中的程序是否出现异常,finally语句总会被执行。区别在于:当出现异常时,finally语句执行后,把异常向上传递到外层try或者默认异常处理器,打印出错消息并退出;没有出现异常时,finally语句执行后,接着执行try/finally语句后面的代码。
try/finally一般用来确保关闭文件、终止服务器的连接调用等。

with/as是try/finally的一个替代方案,通过运行对象的环境管理逻辑来确保终止行为的发生。


异常不仅仅是错误

异常除了错误处理,还可以用到很多地方。
事件通知
终止行为


其他

sys.exc_info()
返回:
三元组(type, value, traceback):type是异常类型;value是异常实例;traceback代表异常最初发生时所调用的堆栈
当使用空的except子句时,无法确定捕捉的异常到底是什么类型的,这时可以通过sys.exc_info来确定:

try:    ...except:    sys.exc_info()
0 0
原创粉丝点击