python异常处理:try_except语句;try_finally语句;raise语句
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 | 用户代码生成的警告 |
1、try-except语句
2、try-finally语句
3、raise语句
参考:
小甲鱼Python第032讲:异常处理:你不可能总是对的| 课后测试题及参考答案
小甲鱼Python第033讲:异常处理:你不可能总是对的2| 课后测试题及参考答案
一、try-except语句
语句格式:
try: 检测范围 except Exception [as reason]: 出现异常(Exception)后的处理代码
try: <语句> #运行别的代码 except <名字>: <语句> #如果在try部份引发了'name'异常 except <名字>,<数据>: <语句> #如果引发了'name'异常,获得附加的数据 else: <语句> #如果没有异常发生
try的工作原理是,当开始一个try语句后,python就在当前程序的上下文中作标记,这样当异常出现时就可以回到这里,try子句先执行,接下来会发生什么依赖于执行时是否出现异常。
- 如果当try后的语句执行时发生异常,python就跳回到try并执行第一个匹配该异常的except子句,异常处理完毕,控制流就通过整个try语句(除非在处理异常时又引发新的异常)。
- 如果在try后的语句里发生了异常,却没有匹配的except子句,异常将被递交到上层的try,或者到程序的最上层(这样将结束程序,并打印默认的出错信息)。
- 如果在try子句执行时没有发生异常,python将执行else语句后的语句(如果有else的话),然后控制流通过整个try语句。
实例
下面是简单的例子,它打开一个文件,在该文件中的内容写入内容,且并未发生异常:
try: fh = open("testfile", "w") fh.write("这是一个测试文件,用于测试异常!!") except IOError: print ("Error: 没有找到文件或读取文件失败") else: print ("内容写入文件成功") fh.close()
try/except语句用来检测try语句块中的错误,从而让except语句捕获异常信息并处理。
如果你不想在异常发生时结束你的程序,只需在try里捕获它。eg:
f = open("我为什么是一个文档.txt") print(f.read()) f.close()
以上代码在“我为什么是一个文档.txt”这个文档不存在的时候,Python就会报错说文件不存在:
Traceback (most recent call last): File "C:\Users\14158\Desktop\lalallalalal.py", line 1, in <module> f = open("我为什么是一个文档.txt") FileNotFoundError: [Errno 2] No such file or directory: '我为什么是一个文档.txt'
显然这样的用户体验很糟糕,因此可以这样修改:
try: f = open("我为什么是一个文档.txt") print(f.read()) f.close() except OSError: print("文件打开的过程出错啦")
但是从程序员的角度来看,导致OSError异常的原因有很多(例如FileExistsError、FileNotFoundError等等),所以可能会更在意错误的具体内容,这里可以使用as把具体的错误信息给打印出来:
try: f = open("我为什么是一个文档.txt") print(f.read()) f.close() except OSError as reason: print("文件打开的过程出错啦,错误的原因是:" + str(reason))
文件打开的过程出错啦,错误的原因是:[Errno 2] No such file or directory: '我为什么是一个文档.txt'
1、针对不同异常设置多个except
你可以不带任何异常类型使用except,如下实例:
try: 正常的操作 ...................... except: 发生异常,执行这块代码 ...................... else: 如果没有异常执行这块代码
以上方式try-except语句捕获所有发生的异常。但这不是一个很好的方式,我们不能通过该程序识别出具体的异常信息。因为它捕获所有的异常。
一个try语句还可以和多个except语句搭配,分别对感兴趣的异常进行检测处理:
try: sum = 1 + '1' f = open("我是一个不存在的文档.txt") print(f.read()) f.close() except OSError as reason: print("文件打开的过程出错啦,错误的原因是:" + str(reason)) except TypeError as reason: print("文件打开的过程出错啦,错误的原因是:" + str(reason))
文件打开的过程出错啦,错误的原因是:unsupported operand type(s) for +: 'int' and 'str'
2、对多个异常统一处理
标准语句:
try: 正常的操作 ...................... except(Exception1[, Exception2[,...ExceptionN]]]): 发生以上多个异常中的一个,执行这块代码 ...................... else: 如果没有异常执行这块代码
except后边还可以跟多个异常,然后对这些异常进行统一的处理:
try: int("abc") sum = 1 + "1" f = open("我是一个不存在的文档.txt") print(f.read()) f.close() except (OSError,TypeError): print("文件打开的过程出错啦,错误的原因是:" + str(reason))
Traceback (most recent call last): File "C:\Users\14158\Desktop\lalallalalal.py", line 2, in <module> int("abc") ValueError: invalid literal for int() with base 10: 'abc'
3、捕获所有的异常
如果你无法确定要对哪一类异常进行处理,只是希望在try语句块里一旦出现异常,可以给用户一个“看得懂”的提醒,那么可以这么做。
............
except:
print("出错了~")
............
不过通常不建议这么做,因为它会隐藏所有程序员未想到并且未做好处理准备的错误,例如当用户输入ctrl+C试图终止程序,却被解释为KeyboardInterrupt异常。另外要注意的是,try语句检测范围内一旦出现异常,剩下的语句将不会执行。
二、try-finally语句
try-finally 语句无论是否发生异常都将执行最后的代码。
try: <语句> finally: <语句> #退出try时总会执行 raise
如果“我是一个不存在的文档”确实存在,open()函数正常返回文件对象,但异常却发生在成功打开文件后的sum = 1 + “1”语句上。此时python将直接跳转到except语句,也就是说,文件被打开了,但并没有执行关闭的命令:
try: f = open("我是一个不存在的文档.txt") print(f.read()) sum = 1 + "1" f.close() except: print("出错啦")
为了实现像这种“就算出现异常,但不得不执行的收尾工作(比如在程序崩溃前保存用户文档)”,引入了finally来扩展try:
try: f = open("我是一个不存在的文档.txt") print(f.read()) sum = 1 + "1" except: print("出错啦") finally: f.close()
如果try语句块中没有出现任何运行时出现的错误,会跳过except语句执行finally语句块的内容。如果出现异常,则会先执行except语句块的内容再执行finally语句块的内容。总之,finally语句块中的内容就是确保无论如何都将被执行的内容。
try: fh = open("testfile", "w") try: fh.write("这是一个测试文件,用于测试异常!!") finally: print ("关闭文件") fh.close() except IOError: print ("Error: 没有找到文件或读取文件失败")
当在try块中抛出一个异常,立即执行finally块代码。finally块中的所有语句执行后,异常被再次触发,并执行except块代码。参数的内容不同于异常。
三、raise语句
raise语法格式如下:
raise [Exception [, args [, traceback]]]
语句中 Exception 是异常的类型(例如,NameError)参数标准异常中任一种,args 是自已提供的异常参数。最后一个参数是可选的(在实践中很少使用),如果存在,是跟踪异常对象。
也许会问,我的代码能不能自己抛出一个异常呢?答案是可以的,可以使用raise语句抛出一个异常:
>>> raise ZeroDivisionError
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
raise ZeroDivisionError
ZeroDivisionError
抛出的异常还可以带参数,表示异常的解释:
>>> raise ZeroDivisionError("除数不能为零!")
Traceback (most recent call last):
File "<pyshell#1>", line 1, in <module>
raise ZeroDivisionError("除数不能为零!")
ZeroDivisionError: 除数不能为零!
eg:
一个异常可以是一个字符串,类或对象。 Python的内核提供的异常,大多数都是实例化的类,这是一个类的实例的参数。定义一个异常非常简单,如下所示:
def functionName( level ): if level < 1: raise Exception("Invalid level!", level) # 触发异常后,后面的代码就不会再执行
注意:为了能够捕获异常,"except"语句必须有用相同的异常来抛出类对象或者字符串。例如我们捕获以上异常,"except"语句如下所示:
try: 正常逻辑 except Exception,err: 触发自定义异常 else: 其余代码
eg:
# 定义函数 def mye( level ): if level < 1: raise Exception,"Invalid level!" # 触发异常后,后面的代码就不会再执行 try: mye(0) # 触发异常 except Exception,err: print 1,err else: print 2