python异常处理一
上一篇 / 下一篇 2017-09-03 23:26:23 / 个人分类:python
异常
异常是指程序中的例外,违例,影响程序正常执行的情况。
异常机制是指程序出现错误后,程序的处理方法。
当出现错误后,程序的执行流程发生改变,程序的控制权转移到异常处理。
如果程序执行过程中发生了异常,我们没有进行异常处理,那么程序就会中止执行下面的代码。但是如果我们进行了异常处理,程序会继续执行下面的代码。
异常的例子:
NameError:尝试访问一个未申明的变量
>>> foo
Traceback (innermost last): File "<stdin>", line 1, in ?
NameError: name 'foo' is not defined
NameError表示我们访问了一个没有初始化的变量.在Python解释器的符号表没有找到那个另人讨厌的变量.我们将在后面的两章讨论名称空间,现在大家可以认为它们是连接名字和对象的"地址簿"就可以了.任何可访问的变量必须在名称空间里列出.访问变量需要由解释器进行搜索,如果请求的名字没有在任何名称空间里找到,那么将会生成一个NameError异常.
ZeroDivisionError:除数为零
>>> 1/0
Traceback (innermost last): File "<stdin>", line 1, in ?
ZeroDivisionError: integer division or modulo by zero
我们边的例子使用的是整数,但事实上,任何数值被零除都会导致一个ZeroDivisionError
异常.
SyntaxError: Python解释器语法错误
>>> for
File "<string>", line 1Edit By Vheavens
for
^
SyntaxError: invalid syntax
SyntaxError异常是唯一不是在运行时发生的异常.它代表Python代码中有一个不正确的结构,在它改正之前程序无法执行.这些错误一般都是在编译时发生, Python解释器无法把你的脚本转化为Python字节代码.当然这也可能是你导入一个有缺陷的模块的时候.
IndexError:请求的索引超出序列范围
>>> aList = []
>>> aList[0]
Traceback (innermost last): File "<stdin>", line 1, in ?
IndexError: list index out of range
IndexError在你尝试使用一个超出范围的值索引序列时引发.
KeyError:请求一个不存在的字典关键字
>>> aDict = {'host': 'earth', 'port': 80}
>>> print aDict['server'] Traceback (innermost last):
File "<stdin>", line 1, in ? KeyError: server
映射对象,例如字典,是依靠关键字(keys)访问数据值的.如果使用错误的或是不存在的键请求字典就会引发一个KeyError异常.
IOError:输入/输出错误
>>> f = open("blah") Traceback (innermost last):
File "<stdin>", line 1, in ?
IOError: [Errno 2] No such file or directory: 'blah'
类似尝试打开一个不存在的磁盘文件一类的操作会引发一个操作系统输入/输出(I/O)错误.任何类型的I/O错误都会引发IOError异常.
AttributeError:尝试访问未知的对象属性
>>> class myClass(object):
... pass
...
>>> myInst = myClass()
>>> myInst.bar = 'spam'
>>> myInst.bar
'spam'
>>> myInst.foo
Traceback (innermost last): File "<stdin>", line 1, in ?
AttributeError: foo
异常的定义
一个try语句可以对应一个或多个except子句,但只能对应一个finally子句,或是一个try-except-finally复合语句
try:
<语句>#可能发生异常的代码
except<名字>:
<语句>#如果在try部份引发了'name'异常
except<名字>,<异常参数>:
<语句>#如果引发了‘name’异常,获得附加的异常对象
else:
<语句>#如果没有异常发生
将可能发异常的语句,放到try语句块中,让except语句捕获异常信息并处理。
#encoding=utf-8
import sys
import traceback
try:
1/0
print "never executed!"
except ZeroDivisionError,e:
print "ZeroDivisionError occur"
print e.message
print e.args
except:
print "other Error occur!"
else:
print "no Error occur!"
--------------------------------------
ZeroDivisionError occur
integer division or modulo by zero
('integer division or modulo by zero',)
#没有异常直接执行else
#coding=utf-8
try :
fp = open("c:\\file.txt", 'w')
fp.write("test")
fp.close()
except IOError :
print "文件写入失败!"
else :
print "文件写入成功!"
文件写入成功!
小练习:
1用户输入一个文件的绝对路径
2如果没有异常,则打印文件的内容
3有异常,则重新让用户输入文件的绝对路径
#思路:把打开文件的放在try中,出现异常的话执行except,无异常时执行else语句
#encoding=utf-8
while 1:
filename=raw_input("请输如一个文件名称:")
try:
f=open(filename,"r")
except IOError as e: #捕获异常,且把异常信息赋值给变量e
print e
else:
print f.read()
Break
F:\python\异常>python 09031.txt
请输如一个文件名称:f:\\23.ttx
[Errno 2] No such file or directory: 'f:\\\\23.ttx'
请输如一个文件名称:f:\\3.txt
锘?encoding=utf-8
print len("濂藉ソ瀛︿範锛屽ぉ澶╁悜涓婏紒")
print len("濂藉ソ瀛︿範锛屽ぉ澶╁悜涓婏紒".encode("utf-8"))
print len("濂藉ソ瀛︿範锛屽ぉ澶╁悜涓婏紒".encode("gbk"))
print len("濂藉ソ瀛︿範,澶╁ぉ鍚戜笂!")
print len("濂藉ソ瀛︿範,澶╁ぉ鍚戜笂!".encode("utf-8"))
print len("濂藉ソ瀛︿範,澶╁ぉ鍚戜笂!".encode("gbk"))
#可以把所有的全部放在try中直接执行完了,就不用写else语句
#coding=utf-8
while 1:
file_path=raw_input("please input the file path:")
try:
fp=open(file_path)
print fp.readline()
fp.close()
break
except IOError:
print "file path does not exists!"
continue
except Exception,e: #为了避免出现除IOError之外的异常
print e
continue
异常工作原理
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,
当异常出现并捕获后继续执行后续的代码,try子句先执行,接下来会发生什么依赖
于执行时是否出现异常。
如果当try后的语句执行时发生异常,python就跳出try并执行第一个匹配该异常的
except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发
新的异常)。
多个except时,只执行第一个except下边的except都不执行了,但接下来的程序会继续执行
#encoding=utf-8
import sys
try:
1/0 #出现异常后,try语句里面后面的语句将不被执行
print "never executed!"
except ZeroDivisionError,e:
print "ZeroDivisionError occur"
print e.message
print e.args
print dir(e)
except IOError,e:
print "IO Error occur"
except:
print "other Error occur!"
print "Done"
F:\python\异常>python多个except.txt
ZeroDivisionError occur
integer division or modulo by zero #错误的信息
('integer division or modulo by zero',)
['__class__', '__delattr__', '__dict__', '__doc__', '__format__', '__getattribute__', '__getitem__', '__getslice__', '__hash__', '__init__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__setstate__', '__sizeof__', '__str__', '__subclasshook__', '__unicode__', 'args', 'message']
Done
如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印缺省的出错信息)。
>>> try:
... f=open("f:\\11.txt")
... except ZeroDivisionError,e:
... print e
...
Traceback (most recent call last):
File "<stdin>", line 2, in <module>
IOError: [Errno 2] No such file or directory: 'f:\\11.txt'
>>>
‘’’
如果该层出现异常会被抛到上层的try中
‘’’
#encoding=utf-8
def a():
try:
1/0
except IOError,e:
try:
a()
except Exception,e:
print e
'''
F:\python\异常>python上级异常.txt
integer division or modulo by zero
'''
a()
'''
Traceback (most recent call last):
File "上级异常.txt", line 24, in <module>
a()
File "上级异常.txt", line 6, in a
1/0
ZeroDivisionError: integer division or modulo by zero
'''
‘’’
抛出异常,让上层处理这个异常
‘’’
def a():
try:
raise
#1/0
except IOError,e:
print "function "
print e
try:
a()
except Exception,e:
print "catch exception"
print e
F:\python\异常>python上级异常.txt
catch exception
exceptions must be old-style. classes or derived from BaseException, not NoneType
‘’’
抛出指定异常,让上层捕获这个异常,并且处理这个异常
‘’’
#encoding=utf-8
def a():
try:
raise ZeroDivisionError
#1/0
except IOError,e:
print "function "
print e
try:
a()
except ZeroDivisionError,e: #处理函数抛出来的异常
print "catch exception"
print e #里面没有内容
print "DONE!"
F:\python\异常>python上级异常.txt
catch exception
DONE!
Raise(raise抛出的异常没有异常信息)
Raise抛出的异常可以在任意处捕获,可以在当前try下的except下捕获,也可以在上一层中被捕获
>>> try:
... 1/0
... except ZeroDivisionError,e:
... print e
...
integer division or modulo by zero
>>> try:
... raise ZeroDivisionError
... except ZeroDivisionError,e: #没有异常信息
... print e
...
>>>
如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
#encoding=utf-8
import sys
import traceback
try:
1/1
print "never executed!"
except ZeroDivisionError,e:
print "ZeroDivisionError occur"
print e.message
print e.args
except:
print "other Error occur!"
else:
print "no Error occur!"
----------------------------------------
never executed!
no Error occur!
Ø不管执行try语句是否发生异常,都将会执行finally语句块的语句(如果有的话)。
注意:
捕获异常中可以再嵌套捕获异常,直到不会有新的异常发生为止。
#encoding=utf-8
import sys
import traceback
try:
1/0
print "never executed!"
try:
print "other Error occur!"
except:
try:
except ZeroDivisionError,e:
print "ZeroDivisionError occur"
print e.message
print e.args
except:
try:
print "other Error occur!" #嵌套异常
except:
try:
else:
print "no Error occur!"
print "Done"
except ZeroDivisionError,IOError,TypeError,e:
print "ZeroDivisionError occur"
print e.message
print e.args
总结:
核心笔记:忽略代码,继续执行,和向上移交
try语句块中异常发生点后的剩余语句永远不会到达(所以也永远不会执行).一旦一个异常被引发,就必须决定控制流下一步到达的位置.剩余代码将被忽略,解释器将搜索处理器,一旦找到,就开始执行处理器中的代码.
如果没有找到合适的处理器,那么异常就向上移交给调用者去处理,这意味着堆栈框架立即回到之前的那个.如果在上层调用者也没找到对应处理器,该异常会继续被向上移交,直到找到合适处理器.如果到达最顶层仍然没有找到对应处理器,那么就认为这个异常是未处理的, Python解释器会显示出跟踪返回消息,然后退出
嵌套try的异常捕获
>>> try:
... try:
... 1/0
... except IOError:
... print "IOError occur"
... except Exception,e:
... print e
...
integer division or modulo by zero
>>>
Try-except
>>> def f():
... n=raw_input("请输如一个数:")
... try:
... n_f=float(n)
... except ValueError,e:
... print "error"
...
>>> f()
请输如一个数:z
error
>>>
多个except
>>> def f(obj):
... try:
... n_f=float(obj)
... except ValueError,e:
... print "error"
... except TypeError,e:
... print "类型错误"
...
>>> f(2)
>>> f("3")
>>> f("a")
error
>>> f([1.2.3])
File "<stdin>", line 1
f([1.2.3])
^
SyntaxError: invalid syntax
>>> f([1,2])
类型错误
>>>
except不带任何异常类型,捕获所有的异常
Øexcept可以不带参数,表示捕获所有的异常;如果加了特定的参数,表示捕获特定的
异常。
>>> try:
... f=open("f:\\11.txt")
... except:
... print "error"
...
error
>>>
或者是如下,都能捕获所有异常:
>>> def f(obj):
... try:
... n_f=float(obj)
... except Exception,e:
... print "error"
...
>>> f([13])
TAG:
我的栏目
标题搜索
日历
|
|||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
1 | 2 | 3 | 4 | 5 | 6 | ||||
7 | 8 | 9 | 10 | 11 | 12 | 13 | |||
14 | 15 | 16 | 17 | 18 | 19 | 20 | |||
21 | 22 | 23 | 24 | 25 | 26 | 27 | |||
28 | 29 | 30 |
我的存档
数据统计
- 访问量: 14282
- 日志数: 20
- 建立时间: 2016-10-19
- 更新时间: 2018-01-27