当前位置:首页>python>Python快速入门学习笔记二十二:错误与异常

Python快速入门学习笔记二十二:错误与异常

  • 2026-10-11 07:52:53
Python快速入门学习笔记二十二:错误与异常
❝

Python入门第二十二课,主要是学习了错误与异常,异常处理是程序健壮性的保障,通过捕获并处理运行时错误,实现错误与正常逻辑的分离,避免程序意外崩溃。

  • 理解什么是错误与异常
    • 错误
    • 异常
  • 异常处理
    • 为什么要进行异常处理
    • 异常处理(初级)
    • 捕获指定的类型的异常
    • 验证异常类之间的继承关系
    • 多个 except
    • 获取异常的具体信息
    • 一个 except 捕获不同的异常
    • 完整写法
  • 手动抛出异常
  • 异常传递机制
  • 自定义异常类

理解什么是错误与异常

错误

错误是指:代码本身有语法错误,解释器无法执行代码。—— 无法通过异常处理机制解决。

age = 18if age >= 18# 这一行语法错误,运行时会报错:SyntaxError: expected ':'    print('成年人')

异常

代码语法上没有问题,但执行过程中出现了问题。—— 可以通过异常处理机制解决。

下面列举出几种开发中常见的异常类型:

1、ZeroDivisionError:当除数为 0 时触发。

num1 = 100num2 = 0result = num1 / num2

2、TypeError:当操作的数据类型不正确或不兼容时触发。

result = '10' + 5

3、AttributeError:当对象没有指定的属性或方法时触发。

# 示例1classPerson:def__init__(self, name, age):        self.name = name        self.age = agep1 = Person("John", 25)print(p1.name)print(p1.age)# print(p1.gender) # 访问不存在的属性# 示例2nums = [1, 2, 3]# nums.add(5) # 调用不存在的方法

4、IndexError:当索引超出范围(索引越界)时触发。

nums2 = [1, 2, 3]print(nums2[3])

5、NameError:当使用了不存在的变量时触发。

print(nums3)

6、KeyError:当访问字典中不存在的 key 时触发。

person = {'name': 'John', 'age': 25}print(person['name'])print(person['gender'])

7、ValueError:当值不合法,但类型正确时触发。

int('hello')

Python 中异常类的继承关系(层级关系)可以通过阅读官方文档了解:https://docs.python.org/zh-cn/3.13/library/exceptions.html#exception-hierarchy

❝

BaseException 是所有异常类的父类,Exception 中包含的是开发中常见的业务异常。

异常处理

为什么要进行异常处理

程序运行过程中出现的异常,如果得不到处理,那程序就会立即崩溃,导致后续代码无法执行。

异常处理不是让异常消失,而是将异常捕获到,随后根据异常的具体情况,来执行指定的逻辑。

下面是【未进行异常处理】的代码示例:

print('异常代码前的输出')num_a = 100num_b = 0result = num_a / num_b # 这一行存在 ZeroDivisionErrorprint('异常代码后的输出') # 由于上一行异常未处理,导致这行代码无法执行

异常处理(初级)

核心规则如下:

✦ 将可能出现异常的代码放在try中,出现异常后的处理代码写在except中。

✦ 如果try中的代码出现异常,那try中的后续代码不会执行,并自动跳转到except中。

✦ 如果try中的代码没有异常,那except中的代码就不会执行。

✦ 无论是否发生异常,try-except后面的代码都会继续执行。

✦ 直接写except捕获到Python中所有的异常——实际开发中不推荐这样做。

下面是【进行了异常处理】的代码示例:

print('异常代码前的输出')try:    num_a = 100    num_b = 0    result = num_a / num_b # 这一行存在 ZeroDivisionError    print('异常代码后的输出')except:    print('抱歉,程序出现了异常')print('其他后续代码……')

捕获指定的类型的异常

通过except 异常类的语法来捕获指定的类型的异常,多个这样的语句就能捕获多个不同类型的异常。请看下面的示例代码:

print('欢迎使用本程序')try:    a = int(input('请输入第一个数:'))    b = int(input('请输入第二个数:'))    result = a / b    print(f'{a}除以{b}的结果是:{result}')except ZeroDivisionError:    print('程序异常:0不能作为除数!')except ValueError:    print('程序异常:输入的必须是数字!')print('***** 我是后续的其它逻辑1 ****')print('***** 我是后续的其它逻辑2 ****')

验证异常类之间的继承关系

print(issubclass(ZeroDivisionError, ArithmeticError))  # Trueprint(issubclass(ZeroDivisionError, Exception))  # Trueprint(issubclass(ValueError, Exception))  # Trueprint(issubclass(KeyboardInterrupt, Exception))  # Falseprint(issubclass(KeyboardInterrupt, BaseException)) # True

多个 except

多个except从上往下匹配,匹配成功后不再向下匹配。

print('欢迎使用本程序')try:    a = int(input('请输入第一个数:'))    b = int(input('请输入第二个数:'))    print(x) # 触发 except Exception    result = a / b    print(f'{a}除以{b}的结果是:{result}')except ZeroDivisionError:    print('程序异常:0不能作为除数!')except ValueError:    print('程序异常:输入的必须是数字!')except Exception:    print('程序异常!')print('***** 我是后续的其它逻辑1 ****')print('***** 我是后续的其它逻辑2 ****')

获取异常的具体信息

通过e变量,可以获取异常相关的信息,也可以借助traceback去格式化异常信息。

print('欢迎使用本程序')try:    a = int(input('请输入第一个数:'))    b = int(input('请输入第二个数:'))    print(x) # 触发 except Exception    result = a / b    print(f'{a}除以{b}的结果是:{result}')except ZeroDivisionError:    print('程序异常:0不能作为除数!')except ValueError:    print('程序异常:输入的必须是数字!')except Exception as e:    print('程序异常!')    print(f'异常信息:{e}')    print(f'异常类型:{type(e)}')    print(f'异常参数:{e.args}')    print(f'异常的文件:{e.__traceback__.tb_frame.f_code.co_filename}')    print(f'异常的具体行数:{e.__traceback__.tb_lineno}')# 通过 traceback 来回溯异常import traceback    print(traceback.format_exc())print('***** 我是后续的其它逻辑1 ****')print('***** 我是后续的其它逻辑2 ****')

运行结果:

欢迎使用本程序请输入第一个数:1请输入第二个数:1程序异常!异常信息:name 'x' is not defined异常类型:<class 'NameError'>异常参数:("name 'x' is not defined",)异常的文件:E:\www.py\basic\advanced\chapter29-exception.py异常的具体行数:71Traceback (most recent call last):  File "E:\www.py\basic\advanced\chapter29-exception.py", line 71, in <module>print(x) # 触发 except Exception          ^NameError: name 'x' is not defined***** 我是后续的其它逻辑1 ********* 我是后续的其它逻辑2 ****

一个 except 捕获不同的异常

print('欢迎使用本程序')try:    a = int(input('请输入第一个数:'))    b = int(input('请输入第二个数:'))# print(x) # 触发 except Exception    result = a / b    print(f'{a}除以{b}的结果是:{result}')except (ZeroDivisionError, ValueError, Exception) as e:    msg: str = ''if isinstance(e, ZeroDivisionError):        msg = '0 不能作为除数!'elif isinstance(e, ValueError):        msg = '输入的必须是数字!'    print(f'程序异常!{msg}')import traceback    print(traceback.format_exc())print('***** 我是后续的其它逻辑1 ****')print('***** 我是后续的其它逻辑2 ****')

完整写法

✔ try尝试去做可能出现异常的事情。

✔ except出现异常时的处理(出现异常时怎么补救)。

✔ else如果一切顺利(没有出现异常)要做的事情。

✔ finally无论有没有异常,都要做的事情。

print('欢迎使用本程序')try:    print('try:')    // print(x) # 触发 except Exception    a = int(input('请输入第一个数:'))    b = int(input('请输入第二个数:'))    result = a / b    print(f'\t{a}除以{b}的结果是:{result}')except (ZeroDivisionError, ValueError, Exception) as e:    print('except:')if isinstance(e, ZeroDivisionError):        print('\t程序异常,0不能作为除数!')elif isinstance(e, ValueError):        print('\t程序异常,您输入的必须是数字!')else:        print(f'\t程序异常:{e}')else:    print('else:')    print('\t挺好的,try中的代码没有任何异常!')finally:    print('finally:')    print('\t无论有没有异常,我的计算都结束了!')print('********* 异常处理模块之后的代码 *********')

手动抛出异常

当程序遇到不符合预期情况时,可以使用raise语句手动触发(抛出)异常。

print('欢迎使用年龄判断系统')try:    age = int(input('请输入你的年龄:'))if18 <= age <= 120:        print('成年')elif0 < age <= 18:        print('未成年')else:raise ValueError('年龄应该为0~120的整数')except Exception as e:    print(f'程序异常:{type(e)}{e}')

异常传递机制

如果异常没有被当前代码块所捕获处理,那该异常就会沿着调用链,逐层传递给其调用者。

如果所有调用者,都没有捕获该异常,那最终程序将因【未处理异常】而意外终止。

deftest1():    print('****** test1 开始 ******')    result = '100' + 100    print('****** test1 结束 ******')deftest2():    print('****** test2 开始 ******')try:        test1()except Exception as e:        print(f'程序异常:{type(e)}{e}')    print('****** test2 结束 ******')deftest3():    print('****** test3 开始 ******')    test2()    print('****** test3 结束 ******')test3()

上面代码执行结果如下:

****** test3 开始 ************ test2 开始 ************ test1 开始 ******程序异常:<class 'TypeError'> can only concatenate str (not "int") to str****** test2 结束 ************ test3 结束 ******

自定义异常类

由开发人员自己定义一个异常类,用来表示代码中“更具体、更有业务含义”的异常。

具体规则:定义一个类,类名通常以Error结尾,继承Exception类或它的子类。

classSchoolNameError(Exception):def__init__(self, msg):        super().__init__('【校名异常】' + msg)defcheck_school_name(name):if len(name) > 10:raise SchoolNameError('学校名称过长')else:        print('学校名称合法')try:    n = input('请输入学校名称:')    check_school_name(n)except SchoolNameError as e:    print(f'程序异常:{type(e)}{e}')

最新文章

随机文章