1、什么是异常
错误:是语法或是逻辑上的。
错误发生将导致异常。异常是因为程序出现了错误而在正常控制流以外采取的行为。该行为分为两个阶段:首先是引起异常发生的错误,然后是检测(和采取可能得措施)阶段。
1965年左右,PL/1作为第一个支持异常的主要语言出现。
2、Python中的异常
- NameError 尝试访问一个未声明的变量。
- ZeroDivisionError 除数为0。
- SyntaxError Python解释器语法错误。
- IndexError 请求的索引超出序列范围。
- KeyError 请求一个不存在的字典关键字。
- IOError 输入/输出错误。
- AttributeError 尝试访问未知的对象属性。
3、检测和处理异常
异常可以通过try语句来检测。
(1)try-except语句
try:
try_suite
except Exception[,reason]:
except_suite
(2)包装内建函数
drf safe_float(obj):
try:
retval=float(obj)
except ValueError:
retval='could not convert non-number to float'
return retval
(3)带有多个异常的except语句
try:
try_suite
except Exception1[,reason1]:
except_suite1
except Exception2[,reason2]:
except_suite2
:
(4)处理多个异常的except语句
except (Exception1,Exception2) [,reason]:
(5)捕获所有异常(1.5)
try:
try_suite
except Exception,e:
except_suite
或者(不太推荐):
try:
try_suite
except:
except_suite
例如:
try:
try_suite
except (KeyboardInterupt,SystemExit):
raise
except Exception:
except_suite
2.5中,BaseException成为“所有异常之母”。
-| BaseException
-| KeyboardInterupt
-| SystemExit
-| Exception
-| (all other current built-in exception)
(6)异常参数
except Exception [,reason]:
reason为异常参数,包含来自导致异常的代码的诊断信息的类实例。异常参数本身会组成一个元组,并存储为类实例(异常类的实例)的属性。这里的reason将会是一个Exception类的实例。调用str(reason)总会返回一个良好可读的错误原因。
(7)else子句
在try范围没有异常被检测到时,执行else子句。
(8)finally子句
try:
A
except Exception:
B
else:
C
finally:
D
(9)try-finally子句
try-finally常常用来维持一致的行为而无论异常是否发生。
try:
try_suite
finally:
finally_suite
当finally中所有代码执行完毕后,会继续向上一层引发异常。
①
try:
try:
try_suite
except Exception:
...
finally:
finally_suite
②
try:
try:
try_suite
finally:
finally_suite
except Exception:
...
②可以同时处理在原始的try语句块和finally语句块中发生的错误。
唯一的问题是:当finally中的确发生异常时,会丢失原来异常的上下文信息。
(10)try-except-else-finally
4、上下文管理
(1)with语句
2.5 from __future__ import with_statement 可以使用with语句。
2.6 with成为关键字。
try-except和try-finally的一种特定的配合用法是保证共享的资源的唯一分配,并在任务结束的时候释放它。比如文件(数据、日志、数据库等等),线程资源,简单同步,数据库连接等等。with语句的目标就是应用在这种场景。
with context_expr [as var]:
with suite
with仅能工作于支持上下文管理协议(context management protocol)的对象。显然,只有内建了“上下文管理”的对象才可以与with一起使用。
目前已经有一些支持该协议的对象:
- file
例:
with open('/etc/passwd','r') as f:
for eachLine in f:
...
无论在这一段代码的开始,中间,还是结束时发生异常,会执行清理的代码,此外文件仍会被自动的关闭。
(2)上下文管理协议
上下文对象调用它的__enter()__方法完成with语句块执行前的所有准备工作。
上下文对象的__exit()__方法在with语句块执行结束后被调用,在该方法中进行清理工作。
上下文管理的职责是提供一个上下文对象。这是通过调用__context()__方法来实现的。
5、触发异常
(1)raise语句
raise [SomeException [,args [,traceback]]]
- 第一个参数SomeException是触发异常的名字。它必须是一个字符串,类或者实例。
- 第二个参数可选,用来传递给异常(比如参数,值)。可以是一个单独的对象也可以是一个对象元组。
- 第三个参数,可选。跟踪记录对象
(2)raise语句的用法
- raise exclass 触发一个异常,从exclass生成一个实例(不含任何异常参数)
- raise exclass() 同上,但现在不是类,是类exclass的一个实例,同样没有任何异常参数
- raise exclass,args 同上,同时提供了异常参数args,args可以是一个参数也可以是元组
- raise exclass(args) 同上
- raise exclass,args,tb 同上,同时提供了一个跟踪记录对象tb
- raise exclass,instance 通过实例触发异常(通常是exclass的实例),如果实例是exclass子类的实例,那么这个新异常的类型会是子类的类型;如果实例既不是exclass的实例也不是exclass子类的实例,那么会复制此实例的异常参数去生成一个新的exclass实例
- raise instance 通过实例触发异常:异常类型是实例的类型,等价于raise instance.__class__,instance
- raise string (过时的)触发字符串异常
- raise string,args 同上,同时提供了异常参数args
- raise string,args,tb 同上,同时提供了一个跟踪记录对象tb
- raise 重新触发前一个异常,如果之前没有异常,触发TypeError
6、断言
断言语句语法
assert expression [,arguments]
断言语句:如果断言成功不采取任何措施(类似语句),否则触发AssertionError(断言错误)的异常。可以使用try-except语句捕获AssertionError异常。
我们可以提供一个异常参数给我们的assert命令。
assert 1==0,'One does not equal zero silly!'
7、标准异常
- BaseException(2.5) 所有异常的基类
- SystemExit(2.5之前,Exception的子类SystemExit)Python解释器请求退出
- KeyboardInterrupt(1.6,(2.5之前,StandardError的子类KeyboardInterrupt)) 用户中断执行(通常是输入^C)
- Exception(1.5) 常规错误的基类
- StopIteration(2.2) 迭代器没有更多的值
- GeneratorExit(2.5) 生成器(generator)发生异常来通知退出
- StandardError(2.0) 所有的内建的标准异常的基类
- ArithmeticError(1.5) 所有数值计算错误的基类
- FloatingPointError(1.5) 浮点计算错误
- OverflowError 数值运算超出最大限制
- ZeroDivisionError 除(或取模)零(所有数据类型)
- AssertionError(1.5) 断言语句错误
- AttributeError 对象没有这个属性
- EOFError 没有内建输入,到达EOF标记
- EnvironmentError(1.5)操作系统错误的基类
- IOError 输入/输出操作失败
- OSError 操作系统错误
- WindowsError(1.6) Windows系统调用错误
- ImportError 导入模块/对象失败
- LookupError(1.5) 无效数据查询的基类
- IndexError 序列中没有此索引
- KeyError 映射中没有这个键
- MemoryError 内存溢出错误(对于Python解释器不是致命的)
- NameError 未声明/初始化对象(没有属性)
- UnboundLocalError(1.6) 访问未初始化的本地变量
- ReferenceError(2.2) 弱引用(Weak reference)试图访问已经垃圾回收了的对象
- RuntimeError 一般的运行时错误
- NotImplementedError(1.5) 尚未实现的方法
- SyntaxError Python语法错误
- IndentationError(2.0) 缩进错误
- TabError(2.0) Tab和空格混用
- SystemError 一般的解释器系统错误
- TypeError 对类型无效的操作
- ValueError 传入无效的参数
- UnicodeError(1.6) Unicode相关的错误
- UnicodeDecodeError(2.3) Unicode解码时的错误
- UnicodeEncodeError(2.3) Unicode编码时错误
- UnicodeTranslateError(1.6) Unicode转换时错误
- Warning(2.1) 警告的基类
- Deprecation Warning(2.1) 关于被弃用的特征的警告
- Future Warning(2.3) 关于构造将来语义会有改变的警告
- Overflow Warning(2.2) 旧的关于自动提升为长整型(long)的警告
- PendingDeprecationWarning(2.3) 关于特性将会被废弃的警告
- RuntimeWarning(2.1) 可疑的运行时行为(runtime behavior)的警告
- SyntaxWarning(2.1)可疑的语法的警告
- UserWarning(2.1) 用户代码生成的警告
8、相关模块
exceptions 内建异常(永远不用导入该模块)
contextlib(2.5) 为使用with语句的上下文对象工具
sys 包含各种异常相关的对象和函数(见**)
sys模块中exc_info()函数可以获取异常信息。