首页 > 代码库 > 三十五:python中的异常
三十五:python中的异常
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 | 尚未实现的方法 |
SyntaxError | Python 语法错误 |
IndentationError | 缩进错误 |
TabError | Tab 和空格混用 |
SystemError | 一般的解释器系统错误 |
TypeError | 对类型无效的操作 |
ValueError | 传入无效的参数 |
UnicodeError | Unicode 相关的错误 |
UnicodeDecodeError | Unicode 解码时的错误 |
UnicodeEncodeError | Unicode 编码时错误 |
UnicodeTranslateError | Unicode 转换时错误 |
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")
except IOError as info:
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")
except IOError as info:
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.t
fobj.write("123456789
except IOError,info:
print("异常发生:" ,info.a
else:
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 自定义异常
自定义异常需要到学了类之后再讲。
本文出自 “13088633” 博客,请务必保留此出处http://13098633.blog.51cto.com/13088633/1953893
三十五:python中的异常