Python提供了两个非常重要的功能来处理异常和错误:
1)异常处理try….except
2)断言assert
异常和断言,可以用于我们调试python程序,跟踪程序执行状态,尽快排查问题。
35.1 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尚未实现的方法
SyntaxErrorPython语法错误
IndentationError缩进错误
TabErrorTab和空格混用
SystemError一般的解释器系统错误
TypeError对类型无效的操作
ValueError传入无效的参数
UnicodeErrorUnicode相关的错误
UnicodeDecodeErrorUnicode解码时的错误
UnicodeEncodeErrorUnicode编码时错误
UnicodeTranslateErrorUnicode转换时错误
Warning警告的基类
DeprecationWarning关于被弃用的特征的警告
FutureWarning关于构造将来语义会有改变的警告
OverflowWarning旧的关于自动提升为长整型(long)的警告
PendingDeprecationWarning关于特性将会被废弃的警告
RuntimeWarning可疑的运行时行为(runtime behavior)的警告
SyntaxWarning可疑的语法的警告
UserWarning用户代码生成的警告
35.2 什么是异常
去写一个只读文件,将会出现IO异常——IOError。
什么是异常?
异常是指在程序的运行过程中,某处程序执行发生了意外情况,出错情况,是一个事件。该事件会在程序执行过程中发生,并影响程序的正常运行。
一般python在无法处理程序执行过程中的问题时,就会抛出一个异常,我们要想办法去捕获这个异常,掌握程序执行的一个状态。
35.3 异常如何处理
Python中通过try/except语句来捕获异常;
语法格式如下:
try:
#相关代码,可以是多条
except:#名字即异常的名称,比如IO操作异常就叫IOError
#如果异常捕获到,这里的语句将会执行,可以有多条语句
except,:
#如果引发了‘name‘异常,获得附加的数据
else:
#如果没有捕获到异常,则会执行这条语句,可以有多条语句
实例如下:
35.4 SystemExit方法
SystemExit方法,表示解释器请求退出,这是什么意思呢。我们来看实例分析!
如果我们在第6行判断到了异常,此时没有必要执行第9行及后面的代码,所以我们需要在第6行后退出进程。
代码如下:
再来看下面的程序
那么SystemExit和sys.exit到底什么区别呢?
35.5 SystemExit和sys.exit的区别
SystemExit是一个异常捕获类型,我们可以通过try….except来捕获sys.exit这个异常。
注意try….except嵌套的情况。
35.6 ctrl+c和KeyboardInterrupt异常
程序每隔1秒打印一个*号,如果碰到ctrl+c则退出。
因为pycharm不能检测ctrl+c快捷键,所以在ubuntu的python2.7上做的实验
注意在pycharm中,print函数去掉换行符是print(“*”,end=””)
怎么捕获KeyboardInterrupt呢?
注意1,上面那个程序,当捕获到ctrl+c的时候,异常处理仅仅是一个打印语句。
注意2,else语句分支可不要。
思考:为什么捕获到ctrl+c信号,程序退出了呢,而不像sys.exit函数,捕获它不会退出进程?
35.7 KeyboardInterrupt和SystemExit异常的理解
我们在35.4和35.5的实验中,看到如果我们用try…except System.Exit来捕获sys.exit函数,那么sys.exit不会退出当前进程。而如果我们不去捕获这个信号(sys.exit执行会产生SystemExit信号)。
但是,我们在捕获ctrl+c信号的时候,ctrl+c信号即使被try….except KeyboardInterrupt捕获到,还是照常终止。也就是说,ctrl+c信号不会受try。。。except影响。
最后总结:
Sys.exit如果被try捕获到,函数本身不会生效;
Ctrl+c如果被try捕获到,函数本身会生效。
35.8 使用except而不带异常类型
有时候我们在使用
Try:
Except[异常类型]:
的时候,我们不记得具体的异常类型名称(那么多类型名称很难记住,而且有些还不一定完全知道他的意思),此时怎么办呢?
其实,我们可以在except后面不带具体的异常类型,如:
因为忘记导入time模块,在使用time.sleep(1)的时候发生异常,此时我们没有去捕获具体的异常,而是笼统的,所以第10行语句执行,我们也不知道具体是什么异常。
我们再把这个程序改为正常情况!
注意1,import可以同时导入多个模块,如第3行;
注意2:第8行是为了刷新行缓存;
35.9 except带多种类型的异常
我们不知道是哪个异常,我们试着过滤,一个个去掉
注意:第12行并没有执行,因为我们捕获的是RuntimeError异常,而第8行发生的异常是NameError。
Except带多种类型异常的另一种表示方式:
这种格式会比较好!
35.10 try…finally句型
Try:
Except[异常类型]:
Finally:
#这条语句会无条件执行
Else:
Finally下面的语句第16行会执行。有人会问:如果在第12行,判断到异常后退出进程,finally也会执行吗?
我们试试:
难道是finally会造成sys.exit没有生效吗?
我们再去掉finally
我们发现,去掉finally后,sys.exit会生效(退出进程)。
结论:finally会让进程终止的代码,比如sys.exit执行失效。
注意:finall和else不能同时出现!
35.11 异常的参数
例一:
#------异常带参数的情况-----
#-*-coding:utf8-*-try:
fobj =open("readme.txt")
fobj.write("1234567890")exceptIOError asinfo:print("异常发生:",info.args,info.errno,info.filename,info.__doc__)else:print("没有异常发生....")
#---------输出结果------------
C:\Users\xiajiashan\AppData\Local\Programs\Python\Python36-32\python.exeG:/somy/python/pycharm/Exception/except_argment.py
异常发生: (‘not writable‘,)None None None
Process finished withexit code 0
Except IOErroras info:这条语句,将会把异常产生的信息放在info中。包括参数本身info.args,错误号info.errno,文件名info.filename等。
例二:
#------异常带参数的情况-----
#-*-coding:utf8-*-try:
fobj =open("abc.txt")
fobj.write("1234567890")exceptIOError asinfo:print("异常发生:",info.args,info.errno,info.filename,info.__doc__)else:print("没有异常发生....")
运行结果:
C:\Users\xiajiashan\AppData\Local\Programs\Python\Python36-32\python.exeG:/somy/python/pycharm/Exception/except_argment.py
异常发生: (2, ‘No such fileor directory‘) 2 abc.txt File not found.
Process finished withexit code 0
2表示错误号info.errno
注意:到了python3.x后,不能这样写
#------异常带参数的情况-----
#-*-coding:utf8-*-try:
fobj =open("readme.tfobj.write("123456789exceptIOError,info:
print("异常发生:",info.aelse:print("没有异常发生....")
将会出现下面编译错误:
C:\Users\xiajiashan\AppData\Local\Programs\Python\Python36-32\python.exeG:/somy/python/pycharm/Exception/except_argment.py
File"G:/somy/python/pycharm/Exception/except_argment.py", line 6
except IOError,info:
^
SyntaxError: invalidsyntax
Process finished withexit code 1
35.12 触发异常
Python中,可以通过使用raise触发一个异常,以便通过try。。。except捕获。
语法如下:
Try:
Raise Exception #Exception是标准异常名称,比如NameError
Except Exception: #注意这里的Exception也是一个异常名称
Else:
我们来看实例:
当打印到第10个*号的时候,我们自己触发了一个NameError异常,所以接下来的10个*号不会打印;
因为异常被捕获到了——第15行会执行。
注意:第11行不能有冒号;而且raise后面的异常必须是标准异常;
35.13 自定义异常
自定义异常需要到学了类之后再讲。
原文:http://13098633.blog.51cto.com/13088633/1953893