快速学习Python基础知识详细图文教程13--异常处理

📅 发布时间:2026/8/1 6:04:14
快速学习Python基础知识详细图文教程13--异常处理
来源引用网络知识与某站曹老师视频相互结合学习记录仅供参考Python 基础知识异常处理异常的概念Python 中的异常是指程序运行的过程中出现了错误也叫 Bug即便 Python 程序的语法是正确的在运行它的时候也有可能发生错误运行期检测到的错误被称为异常。异常以不同的类型出现异常即是一个事件该事件会在程序执行过程中发生影响了程序的正常执行一般情况下在Python无法正常处理程序时就会发生一个异常异常是Python对象表示一个错误当Python脚本发生异常时需要捕获处理它否则程序会终止执行。建议参考官方文档错误和异常 https://docs.python.org/zh-cn/3/tutorial/errors.html异常捕获和处理如果出现程序异常不去捕获和处理那么程序遇到异常就会直接终止后续的代码无法继续执行这是不能接受的事情需要尽力地去避免异常 Python 提供了完善的异常处理机制可以实现捕获异常、处理异常最终实现代码继续执行下去从而让程序具体极好的容错性让程序更加的健壮。使用 try...except 语句捕获异常基本语法try:可能会有异常的代码except:出现异常的执行代码# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() try: print(捕获异常正常执行, p1.name) except : print(处理异常确认出现了异常) # 后续其他代码 print(后续其他代码) # 打印输出结果 捕获异常正常执行 None 后续其他代码 进程已结束退出代码为 0# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() # AttributeError: Person object has no attribute sex # p1.sex try: # print(捕获异常正常执行, p1.name) # 设置没有的类属性出现属性异常--AttributeError print(捕获异常属性异常, p1.sex) except : print(处理异常确认出现了异常) # 后续其他代码 print(后续其他代码) # 打印输出结果 处理异常确认出现了异常 后续其他代码 进程已结束退出代码为 0指定异常在 Python 中 , 可以捕获指定类型的异常Python的异常处理能力是很强大的它有很多内置异常可向用户准确反馈出错信息。不过若是try代码块抛出的异常类型和要捕获的异常类型不一致则无法捕获异常捕获所有异常BaseException 异常类是所有类的基类所有异常类均是直接或间接继承 BaseException 异常类Exception 类是继承 BaseException并且有很多具体实现大部分的异常类直接继承 Exception因此一般在开发过程中均是使用 Exception。异常名称Python 标准异常描述说明BaseException所有异常的基类。SystemExit解释器请求退出。KeyboardInterrupt用户中断执行(通常是输入)。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用户代码生成的警告。try/except... except... 多个except语句# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() try: # print(捕获异常属性异常, p1.sex) print(捕获异常除0异常, 10 / 0) except ZeroDivisionError as z: print(f处理异常确认出现了除0异常异常为{z}) except AttributeError as a: print(f处理异常确认出现了属性异常异常为{a}) except Exception as e: print(f处理异常确认出现了异常异常为{e}) # 后续其他代码 print(后续其他代码) # 打印输出结果 处理异常确认出现了除0异常异常为division by zero 后续其他代码 进程已结束退出代码为 0try/except...else 语句try/except 语句还有一个可选的 else 子句如果使用这个子句那么必须放在所有的 except 子句之后。在 Python 的异常处理流程中还可添加一个 else 块当 try 块没有出现异常时程序就会执行 else 块else 子句将在 try 子句没有发生任何异常的时候执行。使用 else 子句比把所有的语句都放在 try 子句里面要好这样可以避免一些意想不到而 except 又无法捕获的异常异常处理并不仅仅处理那些直接发生在 try 子句中的异常而且还能处理子句中调用的函数甚至间接调用的函数里抛出的异常。# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() try: print(捕获异常, 20 / 10) except: print(出现了异常) else: print(没有出现异常这是try/except...else 语句中的else) # 后续其他代码 print(后续其他代码) # 打印输出结果 捕获异常 2.0 没有出现异常这是try/except...else 语句中的else 后续其他代码 进程已结束退出代码为 0try-finally 语句在异常处理中try-finally 语句无论是否发生异常都将会执行最后的代码某些情况下程序在 try 块里打开了一些物理资源例如数据库连接、网络连接和磁盘文件等这些物理资源均务必被显示回收必须要写代码回收资源。finally: 这个代码块的作用后续可做一些文件的读写操作数据库的读写操作、连接、关闭 等 不管有没有异常均会释放一些内存资源的作用# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() try: print(捕获异常, 30 / 10) except: print(出现了异常) else: print(没有出现异常这是try/except...else 语句中的else) finally: print(无论是否有异常都执行这里的代码) # 后续其他代码 print(后续其他代码)多异常捕获假如程序块可能出现异常的种类比较多一般可以使用多异常捕获只要出现其中一个异常就会捕获到。基本语法try:可能会有异常的代码except(异常 1,异常 2,异常 3,......异常 N):出现异常的执行代码# 定义类 class Person(): # 属性姓名 name None # 属性年龄 age None # 实例化类对象 p1 Person() try: print(捕获异常属性异常, p1.name or 40 / 0) except (ZeroDivisionError, AttributeError): print(f处理异常出现了除0异常或者是属性异常) except Exception as e: print(f处理异常确认出现了异常异常为{e}) # 后续其他代码 print(后续其他代码) # 打印输出结果 处理异常出现了除0异常或者是属性异常 后续其他代码 进程已结束退出代码为 0使用 raise 自行引发异常当程序出现错误时系统会自动引发异常。除此之外Python 也允许程序自行引发异常自行引发异常使用 raise 语句来完成。一般是业务逻辑上业务异常问题根据实际需要可以自行引发异常语法格式raise[exceptionName[(reason)]]raise[异常类[(参数)]] 其中参数是可选项大部分是结合自定义异常类一起使用try: age 18 if age 20: # raise 后面若不跟异常类此时是一个运行时异常RuntimeError raise else: print(放行) except Exception as e: print(f捕获处理异常异常为{e}异常类型是{type(e)}) # 打印输出结果 捕获处理异常异常为No active exception to reraise异常类型是class RuntimeError 进程已结束退出代码为 0try: age 18 if age 20: raise Exception else: print(放行) except Exception as e: print(f捕获处理异常类型是{type(e)})自定义异常类在实际开发过程中有些时候系统提供的异常类型不能满足开发的需求时这时候可以通过创建一个新的异常类来拥有自己的异常一般在开发过程中大部分的异常类继承来自 Exception 类建议直接继承 Exception 类即可不需要太复杂化可以直接继承或者间接继承。# 自定义异常类--用于判断字符串长度的若是超长了则抛出异常 # class 类名(可选继承类) class ToolongException(Exception): # 初始化构造魔法方法里面带个参数length def __init__(self, length): self.length length # 再打印的时候重写__str__魔法方法相当于报错的异常提示以便查看 def __str__(self): return fToolongException length is {self.length}超长了 # 自定义测试函数方法 def name_test(): try: name input(请输入您的姓名) if len(name) 4: # 因为上面ToolongException类里面是有参的构造所以这里必须传入一个参数len(name) raise ToolongException(len(name)) else: print(f如果没有异常则输出自定义输入的字符串name{name}) except ToolongException as tle: print(f捕获处理异常出现了异常:{tle}) # 调用name_test name_test()异常的传递性异常是具有传递性的假如方法 A 调用方法 B方法 B 调用方法 C如果方法 C 代码出现异常并且没有处理异常那么则会传递给方法 B同理如果方法 B 依然没有处理异常则最终会传递给方法 A。# 自定义C方法 def funC(): print(funC()开始) # 设置是否有异常--例如“暂无异常”a 1 / 1 a 1 / 1 print(funC()结束) # 定义B方法 def funB(): print(funB()开始) funC() print(funB()结束) # 定义A方法 def funA(): print(funA()开始) funB() print(funA()结束) # 调用方法funA funA() # 输出结果 funA()开始 funB()开始 funC()开始 funC()结束 funB()结束 funA()结束 进程已结束退出代码为 0设置异常后再次执行测试查看# 自定义C方法 def funC(): print(funC()开始) # 设置是否有异常--设置“除0”异常a 1 / 0 a 1 / 0 print(funC()结束) # 定义B方法 def funB(): print(funB()开始) funC() print(funB()结束) # 定义A方法 def funA(): print(funA()开始) funB() print(funA()结束) # 调用方法funA funA() # 输出结果 Traceback (most recent call last): File XX:\xxxxxx\demo136.py, line 21, in module funA() File XX:\xxxxxx\demo136.py, line 17, in funA funB() File XX:\xxxxxx\demo136.py, line 11, in funB funC() File XX:\xxxxxx\demo136.py, line 5, in funC a 1 / 0 ~~^~~ ZeroDivisionError: division by zero funA()开始 funB()开始 funC()开始 进程已结束退出代码为 1从报错结果排查1、先调用 funA2、然后开始调用 funB3、接着调用 funC开始报错了报错时没有及时处理异常从报错代码起始行一层一层传递处理异常方式方法若明确知晓问题发生在何处可直接在问题发生时进行异常处理不过在实际开发过程中是在业务处理端来直接处理其实在哪一层处理语法上均是可以的建议可根据实际开发来。# 自定义C方法 def funC(): print(funC()开始) # 设置是否有异常--设置“除0”异常a 1 / 0 a 1 / 0 print(funC()结束) # 定义B方法 def funB(): print(funB()开始) funC() print(funB()结束) # 定义A方法 def funA(): print(funA()开始) funB() print(funA()结束) # 异常块 try: funA() except Exception as e: print(f捕获处理异常{e}) # 输出结果 funA()开始 funB()开始 funC()开始 捕获处理异常division by zero 进程已结束退出代码为 0异常块是从方法 funA() 最顶层开始捕获 当然亦可以在 B 层、C 层捕获这里说明异常是具有传递性的会一层层往上传递一般建议可以在最顶层处处理。未完待续......