Python基础——异常

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()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值