Python使用try语句实现异常处理。try语句包围着可能引发异常的其他语句。try语句以关键字try开头,后续一个冒号(:)和一个可能在其中引发异常的代码。try语句可指定一个或多个except子句,它们紧接在try suite之后。每个except子句都指定了零个或多个异常类名,它们代表要由except子句处理的异常类型。可在except子句中指定一个标志符,程序用它引用被捕捉的异常对象。处理程序利用标识符从异常对象获取也异常有关的信息。如果except子句中没有指定异常类型,就称为"空白except子句"。这种子句会捕捉所有异常类型。在最后一个except子句之后,可选择性地添加一个else子句。如果try suite中的代码没有引发异常,就会执行else子句中的代码。如果try语句没有指定except子句,那就必须包含一个finally子句----该子句肯定会执行,无论是否发生异常。
在try语句中同时包括except和finally子句是语法错误,可接受的组合形式只有:
1 try:
...... #可能得到异常的语句
except #锁定是哪种异常 (可以有多个except语句) exceptException,e: #捕获所有异常信息传递给变量 e...... #出现异常的处理方法
2 try:
......
except.......
else......
3 try:
......
finally #仅检查异常并做一些必要的清理工作 (仅能有一个finally语句)........
一旦程序代码导致异常,或Python解释器检测到问题,代码或解释器就会“引发”一个异常。有的程序员将程序中发生异常的位置称为“引发点”。异常是一些类的对象,这些类都是从Exception类继承的。如果在一个try suite中发生异常,这个try suite会立即“超时”(即立即终止),程序控制权会移交给try suite之后的第一个except处理程序(如果有的话),接着解释器搜索可对这种异常类型进行处理的第一个except处理程序。解释器为了确定相匹配的except,需要将引发的异常的类型与每个except处理程序的异常类型比较,直到最终发现相匹配的为止。如类型完全一致,或引发的异常的类型是except处理程序的异常类型的一个派生类,就表明发生了匹配。如果try suite中没有发生异常,解释器将忽略用于try语句的异常处理程序,并执行try语句的else子句(如果有的话)。如果没有发生异常,或者某个except子句成功处理了异常,程序会从try语句之后的下一个语句恢复执行。如果在某个语句中发生了一个异常,但该语句不在一个try suite 中,而是一在一个函数中,那么包含那个语句的函数会立即终止,解释器会试图在(发出)调用(的)代码中查找一个封闭的try语句,这个过程称为“堆栈辗转开解”(Stacking Unwinding)。
----------------------------------------------------------------------------------------------
python shell
>>> open('abc.txt','r')
Traceback (most recent call last):
File "", line 1, in
IOError: [Errno 2] No such file or directory: 'abc.txt'
打开一个不存在的文件abc.txt 文件,当系统找不到abc.txt 文件时,就会抛出给我们一个IOError类型的错误,No such file or directory:abc.txt (没有abc.txt这样的文件或目录)
Try...except...
假如,我们已经知道这种类型的错误,那么就可以通过一个异常扑捉来扑捉这个错误。我们可以通过try...except 来接收这个错误。打开文件写入:
try:
open("abc.txt",'r')
except IOError:
pass
再来运行程序就会看不到任何错误,因为我们用except 接收了这个IOError错误。pass 表示实现了相应的实现,但什么也不做。
假如我不是打开一个文件,而是输出一个没有定义的变量呢?
try:
print aa
except IOError:
pass
显然,在上面的代码中我并没有对aa 赋值,运行结果:
Traceback (most recent call last):
File "/home/fnngj/py_se/tryy.py", line 3, in
print aa
NameError: name 'aa' is not defined
我们已经用except 接收错误了,为什么错误还是还是抛出来了。如果你细心会发现这一次的错误类型是NameError ,而我接收类型是IOError ,所以要想接收这个print的错误,那么需要修改接收错误的类型为NameError
虽然,我知道print 语句是可能会抛一个NameError 类型的错误,虽然接收了这个类型错误,但我不知道具体的错误提示信息是什么。那么,我能不能把错误信息打印出来呢?当然可以:
try:
print aa
except NameError, msg:
print msg
我们在接收错误类型的后面定义一个变量msg用于接收具体错误信息, 然后将msg接收的错误信息打印。再来运行程序:
name 'aa' is not defined
现在只打印了一行具体错误信息。
异常的抛出机制:
1、如果在运行时发生异常,解释器会查找相应的处理语句(称为handler).
2、要是在当前函数里没有找到的话,它会将异常传递给上层的调用函数,看看那里能不能处理。
3、如果在最外层(全局“main”)还是没有找到的话,解释器就会退出,同时打印出traceback以便让用户找到错误产生的原因。
注意:虽然大多数错误会导致异常,但一个异常不一定代表错误,有时候它们只是一个警告,有时候它们可能是一个终止信号,比如退出循环等。
try...finally...
try...finally...子句用来表达这样的情况:
我们不管线捕捉到的是什么错误,无论错误是不是发生,这些代码“必须”运行,比如文件关闭,释放锁,把数据库连接返还给连接池等。
创建文件poem.txt
tryf.py
import time
try:
f = file('poem.txt')
while True: # our usual file-reading idiom
line = f.readline()
if len(line) == 0:
break
time.sleep(2)
print line,
finally:
f.close()
print 'Cleaning up...closed the file'
运行程序(在windows命令提示符或linux终端下运行):
...$ python tryf.py
abc
efg
^CCleaning up...closed the file
Traceback (most recent call last):
File "tryy.py", line 18, in
time.sleep(2)
KeyboardInterrupt
程序读poem.txt文件中每一行数据打印,但是我有意在每打印一行之前用time.sleep方法暂停2秒钟。这样做的原因是让程序运行得慢一些。在程序运行的时候,按Ctrl-c中断/取消程序。
我们可以观察到KeyboardInterrupt异常被触发,程序退出。但是在程序退出之前,finally从句仍然被执行,把文件关闭。
到目前为止,我们只讨论了如何捕捉异常,那么如何抛出异常呢?
Raise抛出异常
使用raise来抛出一个异常: 主动抛出一个异常,想让程序停止,可以主动抛出一个异常,与exit相比:有明确的原因
tryr.py
#coding=utf-8
filename = raw_input('please input file name:')
if filename=='hello':
raise NameError('input file name error !')
程序要求用户输入一个文件名,如果用户输入的文件名是hello ,那么抛出一个NameError的异常,用户输入hello 和NameError异常之间没有任何必然联系,我只是人为的通过raise来这样定义,我当然也可以定义称TypeError ,但我定义的异常类型必须是python提供的。
---------------------------------------------------------------------------------------------------------------------------
1、try...except...语句
我们尝试读取用户的一段输入。按Ctrl-d,看一下会发生什么。
>>> s = raw_input('Enter something --> ')
Enter something --> Traceback (most recent call last):
File "", line 1, in ?
EOFError
Python引发了一个称为EOFError的错误,这个错误基本上意味着它发现一个不期望的 文件尾 (由Ctrl-d表示)
接下来,我们将学习如何处理这样的错误。
我们可以使用try..except语句来处理异常。我们把通常的语句放在try-块中,而把我们的错误处理语句放在except-块中。
处理异常
#!/usr/bin/python
# Filename: try_except.py
importsys
try:
s =raw_input('Enter something --> ')
exceptEOFError:
print'\nWhy did you do an EOF on me?'
sys.exit()# exit the program
except:
print'\nSome error/exception occurred.'
# here, we are not exiting the program
print'Done'
输出
$ python try_except.py
Enter something -->
Why did you do an EOF on me?
$ python try_except.py
Enter something --> Python is exceptional!
Done
如果有多重异常情况,那么我们可以写多个except 来解决问题.
2、try ... except...else语句
现在我们来说说这个else语句。Python中有很多特殊的else用法,比如用于条件和循环。放到try语句中,其作用其实也差不多:就是当没有检测到异常的时候,则执行else语句。举个例子大家可能更明白些:
>>> import syslog
>>> try:
... f = open("/root/test.py")
... except IOError,e:
... syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
... syslog.syslog(syslog.LOG_INFO,"no exception caught\n")
...
>>> f.close()
3、finally子句
finally子句是无论是否检测到异常,都会执行的一段代码。我们可以丢掉except子句和else子句,单独使用try...finally,也可以配合except等使用。
例如2.2的例子,如果出现其他异常,无法捕获,程序异常退出,那么文件 f 就没有被正常关闭。这不是我们所希望看到的结果,但是如果我们把f.close语句放到finally语句中,无论是否有异常,都会正常关闭这个文件,岂不是很妙!
>>> import syslog
>>> try:
... f = open("/root/test.py")
... except IOError,e:
... syslog.syslog(syslog.LOG_ERR,"%s"%e)
... else:
... syslog.syslog(syslog.LOG_INFO,"no exception caught\n")
... finally:
>>> f.close()
-------------------------------------------------------------------------------------------------------
Python是面向对象语言,所以程序抛出的异常也是类。常见的Python异常有以下几个
python标准异常
异常名称描述
BaseException
所有异常的基类
SystemExit
解释器请求退出
KeyboardInterrupt
用户中断执行(通常是输入^C)
Exception
常规错误的基类
StopIteration
迭代器没有更多的值
GeneratorExit
生成器(generator)发生异常来通知退出
StandardError
所有的内建标准异常的基类
ArithmeticError
所有数值计算错误的基类
FloatingPointError
浮点计算错误
OverflowError
数值运算超出最大限制
ZeroDivisionError
除(或取模)零 (所有数据类型)
AssertionError
断言语句失败
AttributeError
对象没有这个属性
EOFError
没有内建输入,到达EOF 标记
EnvironmentError
操作系统错误的基类
IOError
输入/输出操作失败
OSError
操作系统错误
WindowsError
系统调用失败
ImportError
导入模块/对象失败
LookupError
无效数据查询的基类
IndexError
序列中没有此索引(index)
KeyError
映射中没有这个键
MemoryError
内存溢出错误(对于Python 解释器不是致命的)
NameError
未声明/初始化对象 (没有属性)
UnboundLocalError
访问未初始化的本地变量
ReferenceError
弱引用(Weak reference)试图访问已经垃圾回收了的对象
RuntimeError
一般的运行时错误
NotImplementedError
尚未实现的方法
SyntaxError
Python 语法错误
IndentationError
缩进错误
TabError
Tab 和空格混用
SystemError
一般的解释器系统错误
TypeError
对类型无效的操作
ValueError
传入无效的参数
UnicodeError
Unicode 相关的错误
UnicodeDecodeError
Unicode 解码时的错误
UnicodeEncodeError
Unicode 编码时错误
UnicodeTranslateError
Unicode 转换时错误
Warning
警告的基类
DeprecationWarning
关于被弃用的特征的警告
FutureWarning
关于构造将来语义会有改变的警告
OverflowWarning
旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning
关于特性将会被废弃的警告
RuntimeWarning
可疑的运行时行为(runtime behavior)的警告
SyntaxWarning
可疑的语法的警告
UserWarning
用户代码生成的警告
Python官网异常类查询文档:
https://docs.python.org/2/library/exceptions.html#bltin-exceptions
http://www.runoob.com/python/python-exceptions.html