前言:
python对异常的采用try…except的语法,
对异常的处理能够提高程序的健壮性和用户的友好性
语法:
try:
<normal statements>
except <except1>: #发生except1异常处理的语句
<excpet1 statements>
except (except1,except2):
<statements>
except <except4> as a: #发生异常时,获取异常
<statements>
except:
<statements> #其他的一切异常
else:
<statements > #木有异常执行的语句
finally:
<statements> #不管有木有异常,都执行的动作,一般的收尾工作,#如关闭文件,连接啊
注意事项:
-
注意细分异常的粒度,不要把一大把的可能会有异常的程序一股脑全放在一段中去,这样异常不好定位。不过也可以先假设一切正常的情况下,进行编程,这样异常定位的比较精准,有利于排除想不到的异常,比如你手抖敲错一个字母,如果你就是异常处理,也会让你蛋疼的
-
注意定义的次序,python的异常是以类的形式建立的,异常有的就是就是继承父类的异常,最顶端的异常是BaseExceptionàExcptionà…., 异常的处理复合短路原则的,就是一旦匹配都一个异常,就直接处理了,不在管后边的异常了。因此如果父类的异常定义子类的异常之前,出现了子类异常时,父类就异常就直接处理了,后面的子类精准的异常就没卵用了
-
注意finally中尽量避免return,break,或者 触发新的异常,
3.1 遗漏异常
python中的异常处理,如果抛出的异常在except没找到对应的exception,那么该异常就会被临时的保存起来。执行完finally后,临时的异常会在此抛出。此时如果在finally中有return,break,或者触发的异常,临时的异常就会被丢弃。
3.2 使用finally return无法得到真正的返回值
如果在finally中有return语句,那么不管try中正常处理返回什么,finally中return 都将先于上面的返回;
例子:def test(a):
try:
if a > 0:
print 'yes'
return 1
else:
print 'No'
return 0
except:
print 'error'
finally:
print 'finally'
return 2
一直返回的都是2
自定义异常
自定义的异常必须直接或者间接的继承Exception这个类,
官网的例子:
>>> class MyError(Exception):
... def __init__(self, value):
... self.value = value
... def __str__(self):
... return repr(self.value)
...
>>> try:
... raise MyError(2*2)
... except MyError as e: # e 只是错误类的实例
... print 'My exception occurred, value:', e.value
...
My exception occurred, value: 4
>>> raise MyError('oops!')
Traceback (most recent call last):
File "<stdin>", line 1, in ?
__main__.MyError: 'oops!'
常见的异常类型
NameError:尝试访问一个未申明
ZeroDivisionError:除数为0
SyntaxError: 语法错误,异常捕获不到的
IndexError:索引超出范围
KeyError:字典关键字不存在
IOError:输入输出错误(找不到文件等)
AttributeError:访问未知对象属性(a={}, a.jjjjj)
ValueError:数值错误 ( int('d') )
TypeError:类型错误('1'+1)
AssertionError:断言错误(assert False)
StopIteration: 再无可遍历的元素 r.next()
ImportError :导入模块失败
KeyboardInterrupt:中断程:Ctrl+c.
StandardError 标准异常。
除StopIteration, GeneratorExit,KeyboardInterrupt 和SystemExit外,其他异常都是StandarError的子类。