Python—异常
###python的异常###
1.异常的类型
BaseException 所有异常的基类
SystemExit 解释器请求退出
Exception 常规错误的基类
AssertionError 断言语句失败
AttributeError 对象没有这个属性
IOError 输入\输出操作失败
OSError 操作系统错误
WindowsError 系统调用失败
ImportError 导入模块失败
SyntaxError Python语法错误
2.异常的概念:
程序在运行的时候,如果python解释器遇到一个错误,就会停止程序的执行
并且提示一些错误的信息,这就是异常
我们在程序开发的时候,很难将所有的特殊请跨都处理,通过异常的捕获可以针对
突发事件做集中处理,从而保证程序的健壮性和稳定性
在程序开发中,如果对某些代码的执行不能确定(程序语法完全正确的前提下)
可以增加try来捕获异常
try:
尝试执行的代码
except:
出现错误的处理
"""
try:
#不能确定正确执行的代码
num = int(raw_input('请输入一个整数'))
except:
print '请输入正确的整数!'
print '*' * 50
"""
如果这个try,except的语句被注释起来的话,
当代码语法没有问题,但是编译报错的时候,
错误代码之后的语句将不再执行
使用这个语句,会报错,但是不会影响接下来的代码的执行
"""
3.捕获异常的工作原理
try的工作原理:
执行一个try语句时,python解释器会在当前程序流的上下文中作标记,当出现异常后,程序流能够根据上下文的标记回到标记位,从而避免终止程序。
1.如果try语句执行时发生异常,程序流跳回标记位,并且向下匹配执行第一个与该异常匹配的except语句,异常处理完后,程序流就通过整个try语句(除非在处理异常时又引发了新的异常)
2.如果没有找到与异常匹配的except句子(也可以不指定异常类型或者指定同样异常类型Excrption,来捕获异常),异常被递交到上层try(若有try的嵌套时),甚至会逐层向上递交异常给程序(逐层上升直到能找到匹配的except句子。实在没有找到时,将程序结束,并打印缺省的错误信息)。
3.如果try句子执行时没有发生异常,python将执行else语句后的语句,然后控制流通过整个try语句
4.异常的预判
根据错误类型来捕获异常:
try:
尝试执行的代码
except 错误类型1:
针对错误类型1,对应的代码处理
except 错误类型2:
针对错误类型2,对应的代码处理
需求:
提示用户输入一个整数
使用8除以用户输入的整数并输出
代码:
try:
# 提示用户输入一个数,这个代码没有问题的情况下,
# 有可能因为用户输入的原因
# 而出现报错,所以就需要利用异常捕获
num = int(raw_input('请输入一个数:'))
res = 8 / num
print res
#下面两个预判,是知道会使程序报错的操作
except ValueError:
print '输入的不是数!'
except ZeroDivisionError:
print '0 不能做除数!'
#但是,错误的情况有时候会很多,总会有预判不到的
#这样就会导致代码的报错
#这种情况是我们不愿意看到的
except Exception as result:
print '未知错误!%s'%result
#下面的代码,是无论是否存在异常,都会执行的代码
finally:
print '无论是否存在异常,都会执行的代码'
# 因为使用了异常捕获,所以不会影响后面的代码的执行
print '*' * 30
"""
finally的作用(用这个语句,可以用来干什么?)
对于没有垃圾回收机制和结构函数自动调用机制(析构函数:当对象
不再被使用的时候,会自动调用的函数)的语言来说,finally语句非常重
要,它能够使程序员保证:无论try块发生了什么,内存总能得到释放。finally可以except同时使用。
注意:
编译器不允许把范围大的异常对象放在前面,假如捕获到了Exception
异常对象,那么就将会停止捕获,而作为其子类的额处理程序就将永远得不到
执行
"""
5.异常的传递
def demo1():
return int(raw_input('请输入整数:'))
def demo2():
return demo1()
# 函数的错误:一级一级的去找,最终会将异常传递到主程序里面
# print demo2()
"""
所以当代码量很多的时候,不需要每一个函数都加异常的捕获
可以直接在最终的主程序加一个捕获
"""
try:
print demo2()
except Exception as result:
print '未知错误 %s' % result
print '*' * 50
6.主动抛出异常 触发异常 raise
raise关键字:手动抛出一个通用的异常类型(Exception),raise关键字后面跟异常的名称,异常名称能够标识出异常类的对象.执行raise语句时,python会创建指定异常类的对象
需求:
提示用户输入密码,如果长度小于8,就抛出异常
def input_passwd():
#提示用户输入密码
pwd = raw_input('请输入密码')
#判断密码的长度是否大于8,大于就返回用户密码
if len(pwd) >= 8:
return pwd
#如果小于8,就主动抛出异常
print '主动抛出异常'
# #创建异常对象
ex = Exception('密码长度不够')
# #主动抛出异常
raise ex
#注意:只抛出异常而不捕获异常,代码会出错
try:
print input_passwd()
except Exception as result:
print result
7.断言
可以理解为提前预言,让人更好的知道错误的原因
def fun(num, div):
assert (div != 0), 'div不能为0'
##如果不添加指定的提示信息 'div不能为0' 的话,编译会提示 AssertionError 断言语句失败并且不提示失败的原因;添加就相当于提示错误在哪里
return num / div
print fun(10,0)
"""
assert语句触发异常:
assert语句根据后面的表达式的真假来控制程序流
若为True,则往下执行;若为False,则中断程序并调用默认的异常处理
同时输出指定的提示信息
"""
8.捕捉多个异常
(1)方法一:
指定一个通用异常,可以捕获多个不同的包含在Exception类中的异常类
try:
语句块
except Exception:
语句块
(2)方法二:
在一个except句子将多个异常作为元组元素列出
try:
语句块
except (IOError,ValueError):
语句块
(3)方法三:
except句子后不带任何异常异常名称,捕获所有异常
9.自定义异常
通过(直接或者间接)继承Exception类来创建一个自定义异常类,自定义的异常类只能通过raise关键字来手动触发
示例:
#直接继承Exception类
class testError(Exception):
def __init__(self,arg):
self.arg = arg
try:
raise testError('just test')
except testErro,info:
print info.args