news 2026/10/3 12:34:03

python学习day09——异常

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
python学习day09——异常

1.异常介绍

1.1 语法错误(Error)

代码写错了,程序根本跑不起来。

# 语法错误,少了冒号 if 5>3 print("ok")

常见语法错误:SyntaxError、缩进错误IndentationError

语法错误必须改代码,无法用异常捕获处理。

1.2 异常(Exception)

代码语法没问题,运行的时候才出错,程序崩溃停止。

num = int("abc") # ValueError print(10 / 0) # ZeroDivisionError

异常可以被捕获,让程序不崩溃。

1.3 Python 中异常类的继承关系

每一个异常属于一个类 顶级异常父类为BaseException

所有的异常都继承自Exception 而 Exception又继承自BaseException

BaseException(所有异常的根) ├── Exception(绝大多数“常规错误/异常”的父类) │ ├── SyntaxError(语法错误) │ ├── ZeroDivisionError(除零) │ ├── IndexError(索引越界) │ ├── KeyError(字典键不存在) │ └── ... ├── SystemExit(程序退出信号) └── KeyboardInterrupt(用户按 Ctrl+C 中断)

2. 异常的处理

我们所谓的处理异常 并不是杜绝异常 或者避免异常 而是当程序运行的时候,出现错误的时候提供解决方案,不中断程序,可以让程序继续执行。

3.try-except处理异常

语法:

try: # 有可能出错的代码 代码块 except 异常类型 as e: # 给异常起名e # 出错之后执行的代码 处理代码
""" 案例分析:观察代码中有可能出现几种异常 ,分别是什么? 1.ValueError: invalid literal for int() with base 10: 'abc' 2.ZeroDivisionError: division by zero """ ​ num1 = int(input("请输入被除数\n")) ​ num2 = int(input("请输入除数\n")) ​ print(num1 / num2) ​ print("程序结束")
""" 使用try-except处理异常 try结构里书写可能出现异常的代码,try不能单独使用 必须结合 except使用 ​ except用于捕获异常 表示出现了对应的异常 将执行except结构内的代码 如果没有捕捉到 或者没有出现对应的异常 就不会执行对应except结构内的代码 ​ """ try: num1=int(input("请输入被除数:\n")) num2=int(input("请输入除数:\n")) print(num1/num2) except ValueError as e: print(f"第一个except 捕捉到了异常{e}") except ZeroDivisionError as e: print(f"第一个except 捕捉到了异常{e}") print("程序结束") ​
3.1 捕获多个不同异常

方式 1:分开写多个 except

try: num1=int(input("请输入被除数:\n")) num2=int(input("请输入除数:\n")) print(num1/num2) except ValueError as e: print(f"第一个except 捕捉到了异常{e}") except ZeroDivisionError as e: print(f"第一个except 捕捉到了异常{e}") print("程序结束") ​

方式 2:一次捕获多个异常(元组)

""" Python支持多个异常书写在一个except中 以简化代码编写 将多个异常书写在一个元组中 """ ​ try: num1 = int(input("请输入被除数\n")) ​ num2 = int(input("请输入除数\n")) ​ print(num1 / num2) ​ except (ValueError,ZeroDivisionError) as e: print(f"捕获到了异常{e}") ​ print("程序结束") ​

Exception可以捕获绝大部分运行时异常

try: 10 / 0 except Exception as e: print("发生异常:", e)

⚠️ 开发规范:尽量捕获具体异常类型,少直接捕获 Exception,提高代码可读性

4.try-except-else处理异常

else:try中的代码执行没有出现异常 将会执行的代码 可以提高可读性,即只要看到else中的代码执行了 就说明try中的代码是没报错的

""" try-except-else处理异常 else不能单独使用 必须结合 try-except使用 else:try中的代码执行没有出现异常 将会执行的代码 可以提高可读性, 即只要看到else中的代码执行了 就说明try中的代码是没报错的 """ try: num1 = int(input("请输入被除数\n")) num2 = int(input("请输入除数\n")) result = num1 / num2 except (ZeroDivisionError,ValueError) as e: print(e) else: print(f"{num1} / {num2} = {result}") print("程序结束")

5.finally处理异常

finally关键字:用于在try-except之后 表示不管是否出现异常 以及异常是否被捕获到 都将执行的代码

""" 使用finally关闭IO资源 """ try: reader = open("a.txt", "w") print(reader.write("666")) print(10 / 0) except IOError as e: print(e) finally: print("reader对象被关闭了") reader.close()

通常用于执行一些必须要进行的清理操作,例如关闭文件、释放资源(如网络连接、数据库连接、锁等)

6. raise抛出异常

raise可以手动制造一个异常,强制报错

""" raise关键字抛出异常 在有些情况下 我们希望程序中的某些错误 直接停止程序 可以使用raise """ def add(a,b): if isinstance(a,(int,float)) and isinstance(b,(int,float)): return a+b else: # 手动抛出异常 会让程序停止 raise TypeError("类型错误,必须为int或者float类型") try: print(add(1,2)) print(add("1",2)) except TypeError as e: print(e) print("程序结束")

7.assert(断言)处理异常

7.1 介绍和使用

assert叫做断言,用来检查一个条件是否为 True。

  • 如果条件为True→ 什么都不发生,代码继续执行

  • 如果条件为False→ 自动抛出AssertionError异常,程序终止

语法:

assert 条件表达式, 错误提示信息

错误提示信息可以省略

""" assert 断言 关键字后边加上一个布尔结果的表达式 如果表达式不成立则会自动创建一个异常对象 AssertionError 类型 如果表达式成立 则不会创建对象 """ def add(a,b): assert isinstance(a,(int,float)) and isinstance(b,(int,float)),"参数类型错误,必须为int或者float" return a+b try: print(add(1,2)) print(add("1",2)) except TypeError as e: print(e) print("程序结束")
""" 使用多个assert关键字来处理异常 """ def add(a,b): assert isinstance(a,(int,float)),"第一个参数类型错误,必须为int或者float" assert isinstance(b,(int,float)),"第二个参数类型错误,必须为int或者float" return a+b try: print(add(1,2)) print(add("1",2)) except TypeError as e: print(e) print("程序结束")
7.2 关键大坑!⚠️ assert 可以被关闭

Python 运行时可以加参数禁用所有 assert

python -O test.py

大写的-O(优化模式)开启之后:所有 assert 语句直接被删掉,不会执行!

👉 所以:绝对不要用 assert 来校验用户输入、业务数据!!

错误示范(千万别这样写)

# 危险!-O运行时断言失效,负数直接放行 def set_age(age): assert age>0, "年龄不能<=0" print(age)

正确做法:业务校验用 if + raise

def set_age(age): if age <= 0: raise ValueError("年龄不能<=0") print(age)
7.4 assert的用途

✅推荐用途(开发调试阶段)

  1. 检查程序内部逻辑是否正确(自检)

  2. 验证函数返回值是否符合预期

  3. 单元测试、调试代码,快速定位 bug

❌禁止用途

  1. 用户输入校验

  2. API 参数校验

  3. 业务规则校验(生产环境不能依赖它)

assert 是调试工具,用来开发阶段做内部自检;生产环境可被关闭,不能当做正式的参数校验手段。

8. 自定义异常

继承Exception父类,就可以做自定义异常

""" 自定义异常:当Python提供的异常不能满足我们的开发需求时 我们就需要自定义异常 """ # 编写类继承异常父类即可 class InputAgeError(Exception): pass class Student: def __init__(self,age): self.age = age @property def age(self): return self.__age @age.setter def age(self,age): if 0<=age<=120: self.__age = age else: raise InputAgeError(f"年龄赋值错误:{age},必须在1~120之间") pass s1=Student(150)

9.异常的传递

""" 异常的传递 如果存在多层try-except嵌套 最内层的try中出现了异常 先由最内层的except来尝试捕获 如果捕获到了 整个嵌套的try-except结构结束 如果捕获不到 则层层向外传递 直到捕获到 或者 整个嵌套try-except结束 """ try: try: try: print(1/0) except NameError as e: print(e) except ZeroDivisionError as e: print(e) except Exception as e: print(e)

10.with关键字处理异常

""" 使用with关键字 简化try-finally的书写 从而更加简洁的管理资源 """ try: with open ('test.txt','w') as f: print(f.write("ttc")) finally: print(f.closed) # True 表示已经自动关闭了
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/10/3 12:30:48

GXUST AI通识课:用TaoToken统一Key打通Cline MCP与Windsurf BYOK

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/10/3 12:30:45

基于PIC24FV16KA304与DRV8818PWPR的工业级步进电机控制方案设计

手头这套电机控制方案&#xff0c;是我在一个圆柱坐标机器人项目里一步步试出来的。主控是 Microchip 的 PIC24FV16KA304&#xff0c;驱动用的是 TI 的 DRV8818PWPR&#xff0c;控制目标就是最常见的双极步进电机。这个组合不花哨&#xff0c;甚至有些“老派”&#xff0c;但它…

作者头像 李华
网站建设 2026/10/3 12:30:26

PIC18F46K22+DRV8818步进电机驱动方案详解与实战排坑

1. 先回答“为什么要分家”&#xff1a;MCU加独立驱动芯片的选型逻辑做工业设备和机器人项目的朋友应该都有体会&#xff1a;步进电机控制方案看着简单&#xff0c;真正落到“跑得稳、不掉步、不烧板”的时候&#xff0c;坑比想象中多。我这次要聊的是一套很典型的组合——TI 的…

作者头像 李华
网站建设 2026/10/3 12:29:38

渐进式JPEG和基线式,我拿同一张图比了体积和解码

摘要 做活动页的同事前几天问我导出 JPG 时那个「渐进式」到底要不要勾。网上两种说法我都见过。一种说渐进式文件更小还能在网慢时先糊后清。另一种说它解码更费劲&#xff0c;放到手机上反而拖后腿。我以前一直凭感觉乱勾&#xff0c;这回干脆拿同一张图两种各存一份挨个比了…

作者头像 李华
网站建设 2026/10/3 12:27:40

基于STM32F042K6与DRV8818PWPR的步进电机驱动设计

从最开始用面包板搭出一套会转的原型&#xff0c;到后来把它塞进一台规划好的小型三轴机器人底座&#xff0c;这套以 STM32F042K6 为控制核心、DRV8818PWPR 做功率驱动的双极步进电机方案&#xff0c;前前后后陪我调了大半年。如果你正在做非标自动化里的小型传送轴&#xff0c…

作者头像 李华
网站建设 2026/10/3 12:26:42

ESP32浏览器改WiFi密码:基于NVS的Web配置工具实现

改个WiFi密码就得把设备拆开、接串口、重新编译烧录&#xff0c;这种窝囊事我干过不止一次。说实话&#xff0c;设备只有一块ESP32、代码也没啥大改动&#xff0c;纯粹为了改两个字符就要折腾大半天&#xff0c;太不值了。后来我仔细翻了ESP-IDF的文档才反应过来——WiFi配置根…

作者头像 李华