python【第五篇】异常处理

作用

程序遇到异常会退出,处理异常增加程序的健壮性

常见异常

NameError               尝试访问一个没有声明的变量
ImportError           无法引入模块或包;可能路径不存在
IndentationError  语法错误(的子类);代码没有正确对齐
SyntaxError           语法错误
IndexError               索引超出序列范围
KeyError               请求一个不存在的字典关键字
IOError        输入输出错误(比如你要读的文件不存在)
AttributeError       尝试访问未知的对象属性
ValueError    传给函数的参数类型不正确,比如给int()函数传入字符串类型
UnboundLocalError  试图访问一个还未被设置的局部变量
KeyboardInterrupt

语法

异常在try块里抛。

try有异常,执行 except ;try无异常,才会执行else

finally:无论try块是否抛异常,永远执行的代码,通常用来执行关闭文件,断开服务器连接等功能。 

例子

try代码块有错误则执行except代码块

 except m,n:m为异常名称,e为变量,异常信息赋值给它

>>> try:
...     r=10/0
...     print('result is %f' % r)
... except ZeroDivisionError,e:
...     print('ZeroDivisionError: %s' %e)
...
ZeroDivisionError: integer division or modulo by zero

 

一下代码均放在exception.py文件中

一旦捕获到即跳出try代码块,跳到对应的exception语句,except类似于if 

try:
    r=10/0
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except NameError, e:
    print('%s' % e)

print('end')

[root@hy tmp]# python exception.py
integer division or modulo by zero
end

 

try没有异常则跳到else语句

try:
    r=10/0
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except NameError, e:
    print('%s' % e)
else:
    print('no exceptions')
print('end')

[root@hy tmp]# python exception.py
integer division or modulo by zero
end

try:
    r=10/1
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except NameError, e:
    print('%s' % e)
else:
    print('no exceptions')
print('end')

[root@hy tmp]# python exception.py
result: 10.000000
no exceptions
end

  

try:
    r=10/1
    print aaa
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except NameError, e:
    print('result: %s' % e)
else:
    print('no exceotions')
print('end')

[root@hy tmp]# python exception.py
result: name 'aaa' is not defined
end

 

无论try有没有捕获到异常,finally语句都会执行 

try:
    r=10/1
    print aaa
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except NameError, e:
    print('result: %s' % e)
else:
    print('no exceotions')
finally:
    print('finally')
print('end')

[root@hy tmp]# python exception.py
result: name 'aaa' is not defined
finally
end

  

父类异常在前则只执行父类异常

try:
    r=10/0
    print('result: %f' % r)
except StandardError, e:
    print('StandardError')
except ZeroDivisionError, e:
    print('%s' % e)
else:
    print('no exceotions')
finally:
    print('finally')
print('end')

[root@hy tmp]# python exception.py
StandardError
finally
end

 

try:
    r=10/0
    print('result: %f' % r)
except ZeroDivisionError, e:
    print('%s' % e)
except StandardError, e:
    print('StandardError')
else:
    print('no exceotions')
finally:
    print('finally')
print('end')

[root@hy tmp]# python exception.py
integer division or modulo by zero
finally
end

  

raise自定义异常

>>> raise NameError('xxx')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: xxx

 

>>> try:
...     raise NameError('xxx')
... except NameError, e:
...     print e
...
xxx

 

>>> import sys
>>> try:
...     10/0
... except:
...     res = sys.exc_info()
...
>>> print res
(<type 'exceptions.ZeroDivisionError'>, ZeroDivisionError('integer division or modulo by zero',), <traceback object at 0xb76eda7c>)

  

class CustomError(Exception):
    def __init__(self,ErrorInfo):
        super().__init__(self) #初始化父类
        self.errorinfo=ErrorInfo
    def __str__(self):
        return self.errorinfo

if __name__ == '__main__':
    try:
        raise CustomError('客户异常')
    except CustomError as e:
        print(e)

  

class DatabaseException(Exception):
    def __init__(self,err='数据库错误'):
        Exception.__init__(self,err)

class PreconditionsException(DatabaseException):
    def __init__(self,err='PreconditionsErr'):
        DatabaseException.__init__(self,err)

def testRaise():
    raise PreconditionsException()

try:
    testRaise()
except PreconditionsException as e:
    print (e)

上下文管理器  

作用:简化释放资源时的异常语法

# 上下文管理器协议
class Sample:
    def __enter__(self):
        print("enter")
        # 获取资源
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        # 释放资源
        print("exit")

    def do_something(self):
        print("doing something")


with Sample() as sample:
    sample.do_something()

更简洁的用法

import contextlib

@contextlib.contextmanager
def file_open(file_name):
    print("file open")
    yield {}
    print("file end")

with file_open("bobby.txt") as f_opened:
    print("file processing")

 

posted @ 2015-12-13 20:47  沐风先生  阅读(301)  评论(0编辑  收藏  举报