更新时间:2025-07-01 00:00点击:62
前言
异常处理是程序用于处理以外情况的代码段,而在代码编写的过程中,经常要进行代码的调试和测试工作。本章将介绍 Python 语言中的异常处理和程序调试的具体使用方法。
一、异常处理
1.1、异常
补充:Exception 类是 Python 中大多数内置异常类的直接或间接父类。当你捕获 Exception 类型的异常时,实际上可以捕获大部分常见的异常情况,但不会捕获一些特殊的、不继承自 Exception 的异常,比如 SystemExit、GeneratorExit 和 KeyboardInterrupt 等。
在人们的工作生活中,做某一件事情的时候,通常并不能很顺序的完成,在做事情的过程中可能会有一些以外的情况发生。比如在开车上班的途中轮胎被扎漏气,就需要先补好车胎再去上班;再比如在写作业时笔坏了,就需要换一支新笔。所以当有意外情况发生时,就需要有对应的解决方法,以便使事情能够继续做下去。对于程序来说,当要完成某一件功能时,有可能也会产生一些以外的情况,这种意外发生的情况在程序中成为异常。
示例1:存在除数为 0 的程序代码示例如下:
print('开始执行除法运算/n/n')while True: str1 = '输入 1 个整数作为第 1 个操作数/n' str2 = '输入 2 个整数作为第 2 个操作数/n' print('开始执行除法运算/n') op1 = int(input(str1)) op2 = int(input(str2)) result = op1 / op2 print('%d / %d = %d' % (op1, op2, result))print('开始执行除法运算/n/n')while True: str1 = '输入 1 个整数作为第 1 个操作数/n' str2 = '输入 2 个整数作为第 2 个操作数/n' try: print('开始执行除法运算/n') op1 = int(input(str1)) op2 = int(input(str2)) result = op1 / op2 print('%d / %d = %d' % (op1, op2, result)) except ZeroDivisionError: # 捕获除数为 0 的异常 print('捕获除数为 0 的异常')# 结果开始执行除法运算开始执行除法运算输入 1 个整数作为第 1 个操作数11输入 2 个整数作为第 2 个操作数0捕获除数为 0 的异常开始执行除法运算输入 1 个整数作为第 1 个操作数
在示例 2 中,当输入第 2 个参数为 0 时,程序继续到下一次循环执行,也就是异常情况得到了处理,程序并没有因为异常而终止。
这段代码以异常使用 try-except 的语法结果,对引发的异常进行捕获和处理,保证程序能继续执行并获得正确。由此得知,对异常进行处理要分为 2 个阶段,第一个阶段是捕获可能引发的异常,第二个阶段是要对发生的异常进行及时的处理。当异常发生时,不仅能检测到异常条件,还可以在异常发生时采取更可靠的补救措施,排除异常。
示例 1 和示例 2 中的 ZeroDivisionError 时除数为 0 的异常类,Python中还有很多内置的异常类,他们分别表示程序中可能发生的各种异常


def division(): '''功能:分苹果''' print("/n===================== 分苹果了 =====================/n") apple = int(input("请输入苹果的个数:")) # 输入苹果的个数 children = int(input("请输入来了几个小朋友:")) result = apple//children # 计算每人分几个苹果 remain =apple-result*children # 计算余下几个苹果 if remain>0: print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result, "个,剩下",remain,"个。") else: print(apple,"个苹果,平均分给",children,"个小朋友,每人分",result,"个。")if __name__ == '__main__': division() # 调用分苹果的函数1. try...except :可以捕获异常并给出相应的处理结果
语法:
try:
block1 #放入可能产生异常的代码
except [ExceptionName [as alias]]
#[ExceptionName [as alias]]:指定要处理的异常,如果不指定则会会处理所有异常
#[as alias]:给异常指定别名,它可以在输出异常内容时通过别名表示
block2 #放入处理结果,如果block1出现异常就会执行block2中的代码
示例
def division(): '''功能:分苹果''' print("/n===================== 分苹果了 =====================/n") apple = int(input("请输入苹果的个数:")) # 输入苹果的个数 children = int(input("请输入来了几个小朋友:")) if apple < children: raise ValueError("苹果太少了,不够分...") result = apple // children # 计算每人分几个苹果 remain = apple - result * children # 计算余下几个苹果 if remain > 0: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个,剩下", remain, "个。") else: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")if __name__ == '__main__': try: # 捕获异常 division() # 调用分苹果的函数 except ZeroDivisionError: # 处理除数为0的异常 print("/n出错了 ~_~ ——苹果不能被0个小朋友分!") except ValueError as e: # 处理值为浮点数的异常 print("/n出错了 ~_~ ——",e) #也可以一次指定多个异常# if __name__ == '__main__':# try: # 捕获异常# division() # 调用分苹果的函数# except (ZeroDivisionError,ValueError) as e: # 处理异常# print(e)2. try...except ...else:在捕获异常时对没有出现异常的情况进行处理
语法:
try:
block1
except [ExceptionName [as alias]]
block2
else:
block3 #没有抛出异常时才执行
示例
def division(): '''功能:分苹果''' print("/n===================== 分苹果了 =====================/n") apple = int(input("请输入苹果的个数:")) # 输入苹果的个数 children = int(input("请输入来了几个小朋友:")) if apple < children: raise ValueError("苹果太少了,不够分...") result = apple // children # 计算每人分几个苹果 remain = apple - result * children # 计算余下几个苹果 if remain > 0: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个,剩下", remain, "个。") else: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")if __name__ == '__main__': try: # 捕获异常 division() # 调用分苹果的函数 except (ZeroDivisionError,ValueError) as e: # 处理异常 print(e) else: print("分苹果顺利完成..") #代码执行正常后再执行3. try...except finally #无论是否出现异常,都要执行一段固定的代码
在实际项目开发中经常用来实现与关闭相关的操作,比如关闭文件
语法:
try:
block1
except [ExceptionName [as alias]]
block2
finally:
block3
示例
def division(): '''功能:分苹果''' print("/n===================== 分苹果了 =====================/n") apple = int(input("请输入苹果的个数:")) # 输入苹果的个数 children = int(input("请输入来了几个小朋友:")) if apple < children: raise ValueError("苹果太少了,不够分...") result = apple // children # 计算每人分几个苹果 remain = apple - result * children # 计算余下几个苹果 if remain > 0: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个,剩下", remain, "个。") else: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")if __name__ == '__main__': try: # 捕获异常 division() # 调用分苹果的函数 except (ZeroDivisionError,ValueError) as e: # 处理异常 print(e) else: print("分苹果顺利完成..") finally: print("进行了一次分苹果操作")4. 使用raise语句抛出异常
在程序开发时如果某个函数或方法可能会产生异常,但我们不想在当前的函数或方法当中来处理这个异常就可以使用raise语句在这个函数或方法当中来抛出异常,抛出异常后,后面的代码不会再执行
语法:
raise [ExceptionName[(reason)]]
#[ExceptionName[(reason)]]:定义抛出的异常名称,如果省略此参数就会把当前的错误原样抛出
#[(reason)]:异常信息的相关描述,如果省略此参数在抛出异常时就不会附带任何描述信息
示例:模拟幼儿园分苹果(每个人至少分到一个)否则抛出异常
def division(): '''功能:分苹果''' print("/n===================== 分苹果了 =====================/n") apple = int(input("请输入苹果的个数:")) children = int(input("请输入来了几个小朋友:")) if apple < children: raise ValueError("苹果太少了,不够分...") result = apple // children remain = apple - result * children if remain > 0: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个,剩下", remain, "个。") else: print(apple, "个苹果,平均分给", children, "个小朋友,每人分", result, "个。")if __name__ == '__main__': try: division() except (ZeroDivisionError,ValueError) as e: print(e)程序调试:Python有两种常用调试方法
断点:在进行程序调试运行的时候想让程序在哪里停下来就在哪里设置断点,一个程序中可以设置多个断点
(1)使用python自带的IDLE进行程序调试
打开调试功能:
打开IDLE → Debug → Debugger
debug控制台按钮作用:
Globals:显示全局变量
Go:继续执行
Step:如果在设置的断点处调用了其他的函数,那么单机这个按钮会进入到函数的内部执行
Over:单步执行
Out:跳出函数与Step对应
Quit:结束调试进行修改
设置断点:
光标放在要设置断点的行,鼠标右击选择 SetBreaKpoint
设置好断点后按F5执行代码进行调试
(2)使用assert断言语句调试程序
在 Python 中,assert是一个用于调试和测试的关键字,它主要用于对程序中的条件进行断言,即检查某个条件是否为真。
基本语法
assert语句的基本语法格式为:assert expression[, arguments]。其中,expression是一个表达式,其结果应该为True或False。arguments是可选的,用于在断言失败时提供额外的信息。
工作原理
如果expression的值为True,则assert语句不做任何事情,程序继续正常执行下一条语句。
如果expression的值为False,则assert语句会触发AssertionError异常,表明程序中出现了与预期不符的情况。如果指定了arguments,则会将arguments的值作为异常的参数传递,以便提供更详细的错误信息。
注意:python -O 文件名.py 命令行选项运行程序时,assert语句可能会被忽略,因此不应该使用assert来执行重要的程序逻辑或处理不可恢复的错误。
示例
验证传入的参数是否符合预期;
在编写测试用例时,验证函数或方法的返回值是否符合预期。
def divide(a, b): assert b != 0, "除数不能为零" return a / b def test_divide(): assert divide(10, 2) == 5,"1" assert divide(5, 1) == 5,"2" try: assert divide(10, 1) == 0,"3" except AssertionError as e: print(f"测试失败: {e}") test_divide()在那些循环或递归等复杂的程序执行过程中,应该始终保持为真的条件
def factorial(n): assert n >= 0, "输入必须是非负整数" if n == 0 or n == 1: return 1 else: result = 1 for i in range(2, n + 1): result *= i assert result > 0, "阶乘结果应该始终为正" return result