如果这种异常没有被处理或者捕捉,程序就会回溯(Traceback),抛出异常信息,终止程序运行。
【1】python异常处理
当我们输入 s=raw_input('Please Enter:') 之后按回车, 然后,我们按下 Ctrl + D
>>> s=raw_input('Please Enter:')
Please Enter:
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
s=raw_input('Please Enter:')
EOFError: EOF when reading a line
这时,我们获得了一个异常情况,EOF -----> end of file 。我们不希望程序崩溃,所以,我们要处理这个异常。
#!/usr/bin/env python/
#coding:utf-8
import sys
try:
s=raw_input('Enter something:')#可能得到异常的语句
except EOFError,e: #锁定是哪种异常
#下面是出现异常后的处理方法
print 'EOFError:',e
sys.exit()#退出
print s
第一次运行结果:
>>>
Enter something:python #最后记得按Enter键
python
第二次运行结果:
>>>
Enter something: #此处直接按ctrl+d
EOFError: EOF when reading a line
try:
s = "hello"
a=1/0#如果外层try子句中的代码引发异常,程序将直接跳转到外层try对应的except子句,而内部的try子句将不会被执行。
try:
print s[0] + s[1]
print s[0] - s[1] #TypeError
except TypeError,e:
print 'TypeError:',e
except: #可以捕获所有异常
print "产生异常"
运行结果:
产生异常
try:
s = "hello"
#a=1/0#如果外层try子句中的代码引发异常,程序将直接跳转到外层try对应的except子句,而内部的try子句将不会被执行。
try:
print s[0] + s[1]
print s[0] - s[1] #TypeError
except TypeError,e:
print 'TypeError:',e
except: #可以捕获所有异常
print "产生异常"
运行结果:
he
TypeError: unsupported operand type(s) for -: 'str' and 'str'
Python是面向对象语言,所以程序抛出的异常也是类。
try:
a=1/0
except ZeroDivisionError,e:#e是一个异常类的实例,包含了来自异常代码的诊断信息。
print 'ZeroDivisionError:',e
print type(e)
print e.__class__
print e.__class__.__doc__
print e.__class__.__name__
运行结果:
ZeroDivisionError: integer division or modulo by zero
<type 'exceptions.ZeroDivisionError'>
<type 'exceptions.ZeroDivisionError'>
Second argument to a division or modulo operation was zero.
ZeroDivisionError
【2】使用raise抛出异常
在程序中主动抛出异常,该怎么办呢?可以使用raise语句,其基本语法如下:
raise [SomeException [, args [,traceback]]
第一个参数,SomeException必须是一个异常类,或异常类的实例
第二个参数是传递给SomeException的参数,必须是一个元组。这个参数用来传递关于这个异常的有用信息。
第三个参数traceback很少用,主要是用来提供一个跟踪记录对象(traceback)
下面举几个例子:
>>> raise NameError
Traceback (most recent call last):
File "<pyshell#14>", line 1, in <module>
raise NameError
NameError
>>> raise NameError() #异常类的实例
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
raise NameError()
NameError
>>> raise NameError,('There is a name error','in abc.txt')
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
raise NameError,('There is a name error','in abc.txt')
NameError: ('There is a name error', 'in abc.txt')
>>> raise NameError('There is a name error','in abc.txt')#注意跟上面一个例子的区别
Traceback (most recent call last):
File "<pyshell#17>", line 1, in <module>
raise NameError('There is a name error','in abc.txt')
NameError: ('There is a name error', 'in abc.txt')
>>> raise NameError,NameError('There is a name error','in abc.txt')#注意跟上面一个例子的区别
Traceback (most recent call last):
File "<pyshell#18>", line 1, in <module>
raise NameError,NameError('There is a name error','in abc.txt')
NameError: ('There is a name error', 'in abc.txt')
我们最常用的还是,只传入第一个参数用来指出异常类型,最多再传入一个元组,用来给出说明信息。
当程序出现错误,python会自动引发异常,也可以通过raise显式地引发异常。一旦执行了raise语句,raise后面的语句将不能执行。
try:
s=None
if s is None:
print 's是空对象!'
raise NameError,'空对象没有长度' #如果引发NameError异常,后面的代码将不能执行
print 'len(s)=',len(s)
except NameError,e:
print e
except TypeError,e:
print e
else:
print 'no error!'
finally:
print 'this is the last step!'
运行结果:
s是空对象!
空对象没有长度
this is the last step!
try:
s='abc'
if s is None:
print 's是空对象!'
raise NameError,'空对象没有长度' #如果引发NameError异常,后面的代码将不能执行
print 'len(s)=',len(s)
except NameError,e:
print e
except TypeError,e:
print e
else:
print 'no error!'
finally:
print 'this is the last step!'
运行结果:
len(s)= 3
no error!
this is the last step!
try:
s=34
if s is None:
print 's是空对象!'
raise NameError,'空对象没有长度' #如果引发NameError异常,后面的代码将不能执行
print 'len(s)=',len(s) #TypeError
except NameError,e:
print e
except TypeError,e:
print e
else:
print 'no error!'
finally:
print 'this is the last step!'
运行结果:
len(s)= object of type 'int' has no len()
this is the last step!
【3】python自定义异常
python允许程序员自定义异常,用于描述python中没有涉及的异常情况,自定义异常必须直接或间接继承Exception类,
自定义异常按照命名规范以"Error"结尾,显式地告诉程序员这是异常。自定义异常使用raise语句引发,而且只能通过人工方式触发。
class MyError(Exception):
def __init__(self,value):
print 'MyError.__init__() is called!'
self.value=value
def __str__(self):
return repr(self.value)
raise MyError(88)
#raise MyError('error!')
运行结果:
MyError.__init__() is called!
Traceback (most recent call last):
File "E:\workspace\python04\oop\kk.py", line 11, in <module>
raise MyError(88)
__main__.MyError: 88
class MyError(Exception):
def __init__(self,value):
print 'MyError.__init__() is called!'
self.value=value
def __str__(self):
return repr(self.value)
#raise MyError(88)
raise MyError('error!')
运行结果
MyError.__init__() is called!
Traceback (most recent call last):
File "E:\workspace\python04\oop\kk.py", line 12, in <module>
raise MyError('error!')
__main__.MyError: 'error!'
from __future__ import division
class DivisionException(Exception):
def __init__(self, x, y):
print 'DivisionException.__init__() is called!'
#Exception.__init__ (self, x, y) #调用基类的__init__进行初始化
self.x = x
self.y = y
if __name__ == "__main__":
try:
x = 6
y = 2
if x%y>0:
print x/y
raise DivisionException(x,y)
except DivisionException,div: #div 表示DivisionException类的实例
print "DivisionExcetion: x/y = %.2f" % (div.x/div.y)
else:
print 'no error!'
finally:
print 'this is the last step!'
运行结果:
no error!
this is the last step!
from __future__ import division
class DivisionException(Exception):
def __init__(self, x, y):
print 'DivisionException.__init__() is called!'
#Exception.__init__ (self, x, y) #调用基类的__init__进行初始化
self.x = x
self.y = y
if __name__ == "__main__":
try:
x = 7
y = 2
if x%y>0:
print x/y
raise DivisionException(x,y)
except DivisionException,div: #div 表示DivisionException类的实例
print "DivisionExcetion: x/y = %.2f" % (div.x/div.y)
else:
print 'no error!'
finally:
print 'this is the last step!'
运行结果:
3.5
DivisionException.__init__() is called!
DivisionExcetion: x/y = 3.50
this is the last step!
#!/usr/bin/env python/
#coding:utf-8
#自定义异常类
class MyInputException(Exception):
def __init__(self,length,least):
Exception.__init__(self)
self.length=length
self.least=least
try:
s=raw_input('输入一个字符串:')
if len(s)<5:
raise MyInputException(len(s),5)
print '字符串的长度符合要求!'
except EOFError:
print '触发了EOF错误,按了Ctrl+D'
except MyInputException,e:
print '输入的字符串长度为%d,期望的长度至少是%d' % (e.length,e.least)
except Exception:
print 'unknown error!'
else:
print 'no error!'
finally:
print 'this is the last step!'
第一次运行结果:
>>>
输入一个字符串:abc
输入的字符串长度为3,期望的长度至少是5
this is the last step!
第二次运行结果:
>>>
输入一个字符串:12345
字符串的长度符合要求!
no error!
this is the last step!
第三次运行结果:
>>>
输入一个字符串:#此处直接按Ctrl+D
触发了EOF错误,按了Ctrl+D
this is the last step!
【4】采用traceback模块查看异常
import traceback
try:
a=1/0
except: #可以捕获所有异常
print 'there is a error!'
traceback.print_exc()
运行结果:
there is a error!
Traceback (most recent call last):
File "E:\workspace\python04\oop\kk.py", line 6, in <module>
a=1/0
ZeroDivisionError: integer division or modulo by zero
我们也可以把异常保存到一个日志文件中,来分析这些异常,请看下面的方法:
import traceback
try:
a=1/0
except: #若except子句不跟任何异常和异常参数,则可以捕获任何异常。
f=open('C:\Users\91135\Desktop\errorLog.txt','a')
traceback.print_exc(file=f) #把traceback.print_exc()打印在屏幕上的信息保存到一个文本文件中。
f.flush()
f.close()
【5】python抛出的常见异常,示例如下:
>>> print var
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
print var
NameError: name 'var' is not defined
>>> var=1/0
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
var=1/0
ZeroDivisionError: integer division or modulo by zero
>>> int float 4.5
SyntaxError: invalid syntax
>>> L=[2,3,4]
>>> L[3]
Traceback (most recent call last):
File "<pyshell#4>", line 1, in <module>
L[3]
IndexError: list index out of range
>>> d={'name':'python','age':23}
>>> d['id']
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
d['id']
KeyError: 'id'
>>> f=open('abc.txt','r')
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
f=open('abc.txt','r')
IOError: [Errno 2] No such file or directory: 'abc.txt'
>>> class A():
def __init__(self,x,y):
self.x=x
self.y=y
>>> a=A(3,4)
>>> print a.z
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
print a.z
AttributeError: A instance has no attribute 'z'
>>> int('abc')
Traceback (most recent call last):
File "<pyshell#16>", line 1, in <module>
int('abc')
ValueError: invalid literal for int() with base 10: 'abc'
>>> s='23'
>>> i=8
>>> print s+i
Traceback (most recent call last):
File "<pyshell#45>", line 1, in <module>
print s+i
TypeError: cannot concatenate 'str' and 'int' objects
>>> assert 1!=1,'error!'
Traceback (most recent call last):
File "<pyshell#46>", line 1, in <module>
assert 1!=1,'error!'
AssertionError: error!
>>> class A(object):
def __init__(self):
pass
def func(self):
raise NotImplementedError
>>> a=A()
>>> a.func()
Traceback (most recent call last):
File "<pyshell#54>", line 1, in <module>
a.func()
File "<pyshell#52>", line 5, in func
raise NotImplementedError
NotImplementedError
定义一个类,一个接口方法func,如果直接调用func,则抛NotImplementedError异常,这样做的目的通常是用来模拟接口。
LookupError:键、值不存在引发的异常。LookupError异常是IndexError、KeyError的基类。
如果我们不确定数据类型是字典还是列表时,可以用LookupError捕获此异常,如下:
try:
d={'age':23,'name':'python'}
print d['id']
except LookupError,e:
print 'LookupError:',e
try:
l=[2,3,2]
print l[3]
except LookupError,e:
print 'LookupError:',e
运行结果:
LookupError: 'id'
LookupError: list index out of range
StandardError 标准异常。
除StopIteration, GeneratorExit, KeyboardInterrupt 和SystemExit外,其他异常都是StandarError的子类。
【6】断言(assert)
assert expression[,reason]
其中assert是断言的关键字。执行该语句的时候,先判断表达式expression,如果表达式为真,则什么都不做;
如果表达式为假,则抛出AssertionErro异常,而且我们传进去的字符串会作为异常类的实例的具体信息存在。
reason跟我们之前谈到的异常类的实例一样。
assert len('python')==len('hello!')#表达式为真,则什么都不做
assert 1==1 #表达式为真,则什么都不做
assert 1==3,'1 is not equal to 3' #表达式为假,则抛出异常
assert异常也可以被try块捕获,如下:
try:
assert 1==2,'1 is not equal to 2'
except AssertionError,e:
print e
print type(e),e.__class__
print e.__class__.__name__
print '%s:%s' % (e.__class__.__name__,e)
运行结果:
1 is not equal to 2
<type 'exceptions.AssertionError'> <type 'exceptions.AssertionError'>
AssertionError
AssertionError:1 is not equal to 2
【7】异常和sys模块
另一种获取异常信息的途径是通过sys模块中的exc_info()函数。该函数回返回一个三元组:(异常类,异常类的实例,跟踪记录对象)。
try:
a=1/0
except:
import sys
tuple=sys.exc_info()
print tuple
for i in tuple:
print i
运行结果:
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0x02686558>)
<type 'exceptions.ZeroDivisionError'> #异常类
integer division or modulo by zero #异常类的实例
<traceback object at 0x02686558> #跟踪记录对象
(完)