Python学习之路—17
异常处理
什么是异常
异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。一般情况下,在Python无法正常处理程序时就会发生一个异常。异常是Python对象,表示一个错误。当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。
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 | 用户代码生成的警告 |
什么是异常处理
python解释器检测到错误,触发异常(也允许程序员自己触发异常)
程序员编写特定的代码,专门用来捕捉这个异常(这段代码与程序逻辑无关,与异常处理有关)
如果捕捉成功则进入另外一个处理分支,执行你为其定制的逻辑,使程序不会崩溃,这就是异常处理。
为什么要进行异常处理
python解析器去执行程序,检测到了一个错误时,触发异常,异常触发后且没被处理的情况下,程序就在当前异常处终止,后面的代码就无法执行。
如何进行异常处理
在Python中处理异常可以使用try except语句。语法如下:
try: 被检测的代码块 except 异常类型: try中检测到错误,执行的代码
成功捕捉异常:
try: print(a) except NameError: print('NameError') print('End') 运行结果: NameError End
如果发生的异常不是捕捉的异常也会报错:
1 try: 2 print(a) 3 except ValueError: 4 print('NameError') 5 print('End') 6 7 运行结果: 8 NameError: name 'a' is not defined
为了应对以上情况我么可以用多分支:
1 a = 'Start' 2 try: 3 print(a) 4 sum() 5 except ValueError: 6 print('NameError') 7 except NameError: 8 print('NameError') 9 except IndexError: 10 print('IndexError') 11 except TypeError: 12 print('TypeError') 13 14 print('End') 15 16 17 运行结果: 18 Start 19 TypeError 20 End
上面这个例子我们没捕捉到一个错误,就要打印之中错误类型。我么虽然知道了错误类型但是不知道具体出了什么错,我们可以用as给错误原因起个别名。
1 a = 'Start' 2 try: 3 print(a) 4 sum() 5 except ValueError as e: 6 print(e) 7 except NameError as e: 8 print(e) 9 except IndexError as e: 10 print(e) 11 except TypeError as e: 12 print(e) 13 14 print('End') 15 16 17 运行结果: 18 Start 19 sum expected at least 1 arguments, got 0 20 End
分支可以帮我们捕获更多的异常,但是却不能捕获所有的异常。这个时候我们就需要使用万能异常
1 li = [1,2,3] 2 try: 3 print(li[3]) 4 except Exception as e: 5 print(e) 6 7 运行结果: 8 list index out of range
有了万能异常我就就能捕获到所有的异常了。那我们就用万能异常不就可以了吗。但是一种事物的存在就有他存在的道理,如果万能异常能满足我们的所有要求,那Python也就不会提供分支了。其实分支和Exception是用在不同的情况下的。
1.如果你想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么一个Exception就足够了。
2.如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了。
try else
我们在学循环的时候学过for循环和while循环都有一个else。其实try也有个else。他们的功能是相似的。
1 try: 2 print(5+8) 3 except NameError as e: 4 print(e) 5 except IndexError as e: 6 print(e) 7 except TypeError as e: 8 print(e) 9 else: 10 print('未发生异常哦') 11 12 13 运行结果: 14 13 15 未发生异常哦
try finally
无论程序有无异常发生都执 finally后面的语句。
1 try: 2 print(5+8) 3 except NameError as e: 4 print(e) 5 except IndexError as e: 6 print(e) 7 except TypeError as e: 8 print(e) 9 else: 10 print('未发生异常哦') 11 finally: 12 print('无论是否发现异常,都答打印') 13 14 15 运行结果: 16 13 17 未发生异常哦 18 无论是否发现异常,都答打印

浙公网安备 33010602011771号