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")
谢谢