Python 异常处理

Python程序运行过程中,当出现异常时就需要异常处理。比如当你当你一个不存在的文件,或者程序的语法出现错误时,Python就会提示你有错误存在。

>>> print 'hello world
  File "<stdin>", line 1
    print 'hello world
                     ^
SyntaxError: EOL while scanning string literal

比如我们打印字符串,少一个引号时,程序就会提醒我们有一个异常语法错误。
Python对异常的处理是很强大的,可向用户准确反馈出错的信息。基于Python一切皆对象的原则,异常也是对象,可对其进行操作。异常基于基类Exception,所有异常都是从该基类继承。Python自动将所有异常名称放置在内建命名空间中,所以我们在程序中不必导入异常模块,可以直接使用。一旦引发异常,而且没有捕捉SystemExit异常,程序执行就会终止,在Python中,异常会被错误自动地触发,也可以由代码触发和截获,当然我们也可以手动使用raise触发一个异常。异常由四个语句处理:

  • try/except:捕捉有Python或者你的程序引起的异常并恢复
  • try/finally:无论异常是否发生,执行清理行为。
  • Raise:手动在代码中触发异常。
  • Assert:有条件的在代码中触发异常。
异常 描述
NameError 尝试访问一个没有声明的变量
ZeroDivisionError 除数为零
SyntaxError 语法错误
IndexError 所以超出序列范围
KeyError 请求一个不存在的字典关键字
IOError 输入输出错误(比如你要读的文件不存在)
ArributeError 尝试访问未知的对象属性
ValueError 传给函数的参数类型不正确

Try/except使用

# -*- coding:utf-8 -*-
#Filename:try_except.py
try:
    a = 12/0
except(ZeroDivisionError,Exception) as e:
    print 'ZeroDivisionError'
print  e
except:
    print '不是ZeroDivisionError异常,其它异常处理分支'
print 'done'

程序的运行结果:

C:\Python27\python.exe F:/python/python_proj/try.py
ZeroDivisionError
integer division or modulo by zero
done
Process finished with exit code 0

该异常处理如下:首先执行try下的语句模块,如果触发异常,则执行过程会调到第一个except语句;如果第一个except定义的异常与该异常匹配,则执行该分支的异常处理代码;若不匹配,则会搜索第一个except,以此类推下去;若所有的except都不匹配,如果跟异常except对应的有else语句,则去执行else分支的代码块。否则,则异常会传递到下一个调用本代码的最高层try代码中去。我们修改上面代码中的异常类型,可以看到:

# -*- coding:utf-8 -*-
#Filename:try_except.py
try:
    a = 12/t
except(ZeroDivisionError,Exception) as e:=
    print 'ZeroDivisionError'
except:
    print '不是ZeroDivisionError异常,其它异常处理分支'
else:
print ‘没有异常,代码正常执行’
print  a
print 'done'

我们使用了一个没有声明的变量t,会触发NameError异常,程序会跳到第二个异常处理分支里去执行代码。运行结果:

C:\Python27\python.exe F:/python/python_proj/try.py
不是ZeroDivisionError异常,其它异常处理分支
done    
Process finished with exit code 0
当我们将代码改为a=12/4时,可以看到下面的运行结果:
C:\Python27\python.exe F:/python/python_proj/try.py
没有异常,代码正常执行
3
done

Process finished with exit code 0

try/finally的使用示例

# -*- coding:utf-8 -*-
#Filename:try_except.py
try:
    a = 12/0
except(ZeroDivisionError,Exception) as e:
    print e
except:
    print '不是ZeroDivisionError异常,其它异常处理分支'
else:
    print '没有异常,代码正常执行'
    print a
finally:
    print '进入finally代码块'
print 'done'

程序的运行结果:

C:\Python27\python.exe F:/python/python_proj/try.py
integer division or modulo by zero
进入finally代码块
done

Process finished with exit code 0

我们修改代码,使得代码分别运行except三个分支,可以看到无论运行哪个异常分支,都会执行到finally的代码。Finally和try子句的联合使用,不管try子句内部是否有异常发生,都会执行finally子句内的代码,所以,一般情况下,finally常常用于关闭文件或者socket的环境中。

Raise使用示例

# -*- coding:utf-8 -*-
#Filename:raise.py
class ShortInputException(Exception):
    '''定义自己的异常类'''
    def __init__(self,length,atleast):
        Exception.__init__(self)
        self.length = length
        self.atleast = atleast
try:
    s = raw_input('请输入一个字符串:-->')
    if(len(s) < 3):
        raise ShortInputException(len(s), 3)
except EOFError:
    print '你输入了一个结束标记EOF'
except ShortInputException,x:
    print 'ShortInputException:输入长度是%d,长度至少是%d' \
    %(x.length, x.atleast)
else:
    print '没有异常发生'

在该程序中,我们首先自己定义一个异常类,然后在代码中使用raise语句触发我们自己定义的异常,运行结果:

C:\Python27\python.exe F:/python/python_proj/raise.py
请输入一个字符串:-->v
ShortInputException:输入长度是1,长度至少是3
Process finished with exit code 0

C:\Python27\python.exe F:/python/python_proj/raise.py
请输入一个字符串:-->hello
没有异常发生
Process finished with exit code 0
《Linux三剑客》视频教程,从零开始快速掌握Linux开发常用的工具:Git、Makefile、vim、autotools、debug,免费赠送C语言视频教程,C语言项目实战:学生成绩管理系统。详情请点击淘宝链接:Linux三剑客