当前位置: 首页 > news >正文

第8篇:从入门到精通:掌握Python异常处理

第8篇:异常处理

内容简介

本篇文章将深入探讨Python中的异常处理机制。您将学习异常的基本概念与类型,掌握使用try-except块处理异常的方法,了解finally语句的作用,以及如何抛出和定义自定义异常。通过丰富的代码示例,您将能够有效地管理程序中的错误,提高代码的健壮性和可维护性。


目录

  1. 异常处理概述
    • 什么是异常
    • 异常的类型
    • 异常处理的重要性
  2. 使用try-except块处理异常
    • try-except语法结构
    • 捕获多个异常
    • 获取异常信息
  3. finally语句
    • finally的作用
    • 结合try-except-finally使用
  4. 抛出自定义异常
    • 定义自定义异常类
    • 抛出自定义异常
    • 捕获自定义异常
  5. 示例代码
    • 基本异常处理示例
    • 捕获多个异常示例
    • finally语句示例
    • 自定义异常示例
  6. 常见问题及解决方法
    • 问题1:如何捕获所有类型的异常?
    • 问题2:except块中不指定异常类型有什么风险?
    • 问题3:什么时候应该使用finally块?
    • 问题4:如何创建和使用自定义异常?
  7. 总结

异常处理概述

什么是异常

**异常(Exception)**是程序在运行过程中发生的错误事件。异常通常会导致程序的正常流程中断,除非被适当处理。Python通过异常处理机制,使程序能够在遇到错误时采取适当的措施,而不是直接崩溃。

异常的类型

Python内置了多种异常类型,常见的包括:

  • SyntaxError:语法错误。
  • TypeError:操作或函数应用于错误类型的对象。
  • ValueError:函数接收到正确类型但不合适的值。
  • IndexError:序列中使用了无效的索引。
  • KeyError:字典中使用了不存在的键。
  • ZeroDivisionError:除以零错误。
  • IOError:输入/输出操作失败。
  • ImportError:导入模块失败。

此外,用户可以根据需要定义自定义异常。

异常处理的重要性

  • 提高程序健壮性:通过捕获和处理异常,防止程序因错误而崩溃。
  • 增强用户体验:向用户提供友好的错误信息,而不是程序直接中断。
  • 便于调试:有助于定位和修复程序中的错误。
  • 资源管理:确保资源(如文件、网络连接等)在异常发生时得到正确释放。

使用try-except块处理异常

try-except语法结构

在Python中,使用try-except块来捕获和处理异常。基本语法如下:

try:# 可能引发异常的代码pass
except ExceptionType:# 处理特定类型异常的代码pass

捕获多个异常

可以在同一个except块中捕获多个异常,或者为不同异常类型定义多个except块。

示例1:同一个except块捕获多个异常

try:# 可能引发异常的代码pass
except (TypeError, ValueError):# 处理TypeError和ValueErrorpass

示例2:为不同异常类型定义多个except

try:# 可能引发异常的代码pass
except TypeError:# 处理TypeErrorpass
except ValueError:# 处理ValueErrorpass

获取异常信息

可以使用as关键字获取异常的详细信息,便于调试和日志记录。

示例

try:result = 10 / 0
except ZeroDivisionError as e:print(f"发生错误:{e}")

finally语句

finally的作用

finally块中的代码无论是否发生异常,都会被执行。它通常用于执行清理操作,如关闭文件、释放资源等。

结合try-except-finally使用

示例

try:f = open("data.txt", "r")data = f.read()
except FileNotFoundError as e:print(f"文件未找到:{e}")
finally:if 'f' in locals():f.close()print("文件已关闭。")

抛出自定义异常

定义自定义异常类

自定义异常类通常继承自内置的Exception类或其子类。

示例

class MyCustomError(Exception):"""自定义异常类"""pass

抛出自定义异常

使用raise关键字可以抛出自定义异常。

示例

def check_value(x):if x < 0:raise MyCustomError("x不能为负数。")

捕获自定义异常

可以在except块中指定自定义异常类型进行捕获和处理。

示例

try:check_value(-1)
except MyCustomError as e:print(f"捕获到自定义异常:{e}")

示例代码

基本异常处理示例

以下示例展示了如何使用try-except块捕获并处理除零错误。

def divide(a, b):try:result = a / bexcept ZeroDivisionError:print("错误:除数不能为零。")else:print(f"结果是 {result}")finally:print("执行结束。")# 调用函数
divide(10, 2)
# 输出:
# 结果是 5.0
# 执行结束。divide(10, 0)
# 输出:
# 错误:除数不能为零。
# 执行结束。

捕获多个异常示例

以下示例展示了如何捕获多个异常类型。

def process_data(data):try:# 假设data应该是一个整数result = 10 / dataexcept (TypeError, ZeroDivisionError) as e:print(f"发生异常:{e}")else:print(f"处理结果是 {result}")# 调用函数
process_data(2)    # 输出: 处理结果是 5.0
process_data(0)    # 输出: 发生异常:division by zero
process_data("a")  # 输出: 发生异常:unsupported operand type(s) for /: 'int' and 'str'

finally语句示例

以下示例展示了如何使用finally块确保资源被释放。

def read_file(filename):try:f = open(filename, "r")content = f.read()except FileNotFoundError as e:print(f"错误:{e}")else:print(content)finally:try:f.close()print("文件已关闭。")except NameError:print("文件未打开,无需关闭。")# 调用函数
read_file("existing_file.txt")
# 输出:
# ...文件内容...
# 文件已关闭。read_file("nonexistent_file.txt")
# 输出:
# 错误:[Errno 2] No such file or directory: 'nonexistent_file.txt'
# 文件未打开,无需关闭。

自定义异常示例

以下示例展示了如何定义、抛出和捕获自定义异常。

class NegativeValueError(Exception):"""自定义异常:负值错误"""passdef calculate_square_root(x):if x < 0:raise NegativeValueError("无法计算负数的平方根。")return x ** 0.5try:print(calculate_square_root(16))  # 输出: 4.0print(calculate_square_root(-4))  # 抛出自定义异常
except NegativeValueError as e:print(f"捕获到自定义异常:{e}")

输出:

4.0
捕获到自定义异常:无法计算负数的平方根。

常见问题及解决方法

问题1:如何捕获所有类型的异常?

原因:在某些情况下,您可能需要捕获所有可能的异常,以防止程序因未处理的错误而崩溃。

解决方法

使用不指定异常类型的except块来捕获所有异常。但需谨慎使用,以避免隐藏潜在的问题。

示例

try:# 可能引发异常的代码pass
except Exception as e:print(f"发生异常:{e}")

注意事项

  • 尽量避免捕获所有异常,除非确实有必要。
  • 确保在捕获所有异常后,能够适当地处理或记录异常信息。

问题2:except块中不指定异常类型有什么风险?

原因:不指定异常类型会导致所有异常都被捕获,包括系统退出异常(如SystemExitKeyboardInterrupt等),可能会掩盖程序中的实际错误。

解决方法

  • 明确指定需要捕获的异常类型。
  • 使用多重except块分别处理不同类型的异常。
  • 保留对关键异常的默认处理,如KeyboardInterrupt

示例

try:# 可能引发异常的代码pass
except ZeroDivisionError:print("捕获到除零错误。")
except TypeError:print("捕获到类型错误。")
except Exception as e:print(f"捕获到其他异常:{e}")

问题3:什么时候应该使用finally块?

原因:当需要确保某些代码在异常发生与否时都被执行,如释放资源、关闭文件或网络连接时。

解决方法

在需要执行清理操作的try块中,使用finally块来放置这些操作。

示例

try:f = open("data.txt", "r")data = f.read()
except FileNotFoundError:print("文件未找到。")
finally:if 'f' in locals():f.close()print("文件已关闭。")

问题4:如何创建和使用自定义异常?

原因:有时内置异常类型无法准确描述特定的错误情况,需要创建自定义异常以提供更具体的错误信息。

解决方法

  1. 定义自定义异常类:继承自内置的Exception类或其子类。
  2. 抛出自定义异常:在适当的位置使用raise语句抛出自定义异常。
  3. 捕获自定义异常:在except块中指定自定义异常类型进行捕获和处理。

示例

class InsufficientFundsError(Exception):"""自定义异常:资金不足"""passclass BankAccount:def __init__(self, balance=0):self.balance = balancedef withdraw(self, amount):if amount > self.balance:raise InsufficientFundsError("余额不足,无法提款。")self.balance -= amountprint(f"成功提款{amount}元。当前余额:{self.balance}元。")# 使用示例
account = BankAccount(100)try:account.withdraw(150)
except InsufficientFundsError as e:print(f"异常:{e}")

输出:

异常:余额不足,无法提款。

总结

在本篇文章中,我们深入探讨了Python中的异常处理机制。通过理解异常的基本概念与类型,学习如何使用try-except块捕获和处理异常,掌握finally语句的应用,以及如何创建和使用自定义异常,您已经掌握了有效管理程序错误的核心技巧。异常处理不仅能提高代码的健壮性和用户体验,还能使您的程序在面对意外情况时更加稳定和可靠。

学习建议

  1. 实践异常处理项目:通过实际项目,如文件处理、网络请求等,巩固所学知识。
  2. 深入学习异常链与上下文:了解异常的链式处理和上下文管理,提升异常处理的灵活性。
  3. 优化代码设计:结合异常处理与设计模式(如策略模式、责任链模式),提高代码的健壮性和可维护性。
  4. 编写文档与测试:为异常处理逻辑编写清晰的文档和单元测试,确保代码的可靠性。
  5. 参与社区与开源项目:通过参与开源项目,学习他人的异常处理实践,提升编程能力。
  6. 阅读相关书籍和文档:如《Python编程:从入门到实践》、《Fluent Python》,系统性地提升Python编程技能。

如果您有任何问题或需要进一步的帮助,请随时在评论区留言或联系相关技术社区。

相关文章:

第8篇:从入门到精通:掌握Python异常处理

第8篇&#xff1a;异常处理 内容简介 本篇文章将深入探讨Python中的异常处理机制。您将学习异常的基本概念与类型&#xff0c;掌握使用try-except块处理异常的方法&#xff0c;了解finally语句的作用&#xff0c;以及如何抛出和定义自定义异常。通过丰富的代码示例&#xff0…...

设计模式-结构型-装饰器模式

装饰器模式&#xff08;Decorator Pattern&#xff09;是结构型设计模式中的一种&#xff0c;它允许你通过将对象封装在一个新的对象中&#xff0c;来动态地添加新的功能&#xff0c;而无需改变原对象的结构。装饰器模式的核心思想是“将功能附加到对象上”&#xff0c;它是一种…...

git详细使用教程

文章目录 一、 git介绍与安装1、git介绍2、git的安装3、git使用前的说明 二、git的基础使用1、走进git之前2、git基础使用1、git init 项目初始化&#xff08;init&#xff09;成仓库&#xff08;repository&#xff09;2、git add 管理文件3、git commit 把文件提交到仓库&…...

java实现word转html(支持docx及doc文件)

private final static String tempPath "C:\\Users\\xxx\\Desktop\\Word2Html\\src\\test\\";//图片及相关文件保存的路径public static void main(String argv[]) {try {JFileChooser fileChooser new JFileChooser();fileChooser.setDialogTitle("Select a …...

搜维尔科技:Xsens人形机器人解决方案的优势

Xsens 致力于推动人形机器人技术的发展&#xff0c;塑造机器人与人类环境无缝融合的未来&#xff0c;通过创新精确和协作&#xff0c;协助生产和服务&#xff0c;改善人类生活和产业。 Xsens通过人形跟随捕捉详细的人体运动数据&#xff0c;使机器人能够学习类人的动作&#x…...

【王树森搜索引擎技术】概要01:搜索引擎的基本概念

1. 基本名词 query&#xff1a;查询词SUG&#xff1a;搜索建议文档&#xff1a;搜索结果标签/筛选项 文档单列曝光 文档双列曝光 2. 曝光与点击 曝光&#xff1a;用户在搜索结果页上看到文档&#xff0c;就算曝光文档点击&#xff1a;在曝光后&#xff0c;用户点击文档&…...

《Java核心技术II》可中断套接字

4.2.4 可中断套接字 SocketChannel可以中断套接字 SocketChannel channel.open(new InetSocketAddress(host,port)); 通道(channel)并没有与之相关联的流&#xff0c;实际上&#xff0c;所拥有的read和write方法都是通过Buffer对象实现的。 如果不想处理缓冲区&#xff0c;…...

基于 Python 的深度学习的车俩特征分析系统,附源码

博主介绍&#xff1a;✌stormjun、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;&…...

C#读写ini配置文件保存设置参数

本示例使用设备&#xff1a;https://item.taobao.com/item.htm?spma21dvs.23580594.0.0.52de2c1b5P5rkA&ftt&id22173428704 [DllImport("kernel32", CharSet CharSet.Unicode)] public static extern uint GetPrivateProfileString(string lpAppName, stri…...

SwanLab环境变量列表

文章目录 环境变量全局配置服务配置登录认证其他 环境变量 ⚙️完整环境变量1 -> Github、⚙️完整环境变量2 -> Github 全局配置 环境变量描述默认值SWANLAB_SAVE_DIRSwanLab 全局文件夹保存的路径用户主目录下的 .swanlab 文件夹SWANLAB_LOG_DIRSwanLab 解析日志文件…...

深度学习入门-CNN

一、CNN是什么 CNN&#xff0c;即卷积神经网络&#xff08;convolutional neural network&#xff09;&#xff0c;是用于预测的标准神经网络架构。在人工智能的广阔领域中&#xff0c;CNN被用于图像识别、语音识别等各种场合&#xff0c;CNN通过模拟人类视觉皮层的神经元连接方…...

微服务网关,如何选择?

什么是API网关 API网关&#xff08;API Gateway&#xff09;是微服务架构中的一个关键组件&#xff0c;它充当了客户端与后端服务之间的中间层。其主要功能包括请求路由、协议转换、负载均衡、安全认证、限流熔断等。通过API网关&#xff0c;客户端无需直接与多个微服务交互&a…...

SpringBoot集成Mqtt服务实现消费发布和接收消费

该项目介绍了docker环境下如何安装mqtt和springboot集成mqtt服务 前述 MQTT(Message Queuing Telemetry Transport)是一种轻量级的消息传输协议,设计用于在资源受限的设备和低带宽、不可靠的网络连接中高效地传输数据。主要用于物联网设备传输,设备之间可以高效地交换数据…...

在Mac mini上实现本地话部署AI和知识库

在Mac mini上实现本地话部署AI和知识库 硬件要求&#xff1a;大模型AI&#xff0c;也叫LLM&#xff0c;需要硬件支持&#xff0c;常见的方式有2种&#xff1a;一种是采用英伟达之类支持CUDA库的GPU芯片或者专用AI芯片&#xff1b;第二种是采用苹果M系列芯片架构的支持统一内存架…...

一个方法被多个线程同时调用,确保同样参数的调用只能有一个线程执行,不同参数的调用则可以多个线程同时执行

我们知道通过lock一个固定静态object给代码段加同步锁&#xff0c;可以让多个线程的同时调用以同步执行&#xff0c;因此可以利用字典来给不同参数分配不同的静态对象&#xff0c;方法中不同的参数调用锁住各自不同的静态对象即可实现不同参数不加锁&#xff0c;相同参数才加锁…...

3. MySQL事务并发的问题与解决方法

一. 并发事务带来的问题 并发会造成事务间出现脏读&#xff0c;不可重复读&#xff0c;幻读现象。 1. 脏读 一个事务在处理过程中读取了另外一个事务未提交的数据。若另外一个事务回滚&#xff0c;则读取到的数据是无效的&#xff0c;又称为脏读。 2. 不可重复读 在一个事务…...

25/1/15 嵌入式笔记 初学STM32F108

GPIO初始化函数 GPIO_Ini&#xff1a;初始化GPIO引脚的模式&#xff0c;速度和引脚号 GPIO_Init(GPIOA, &GPIO_InitStruct); // 初始化GPIOA的引脚0 GPIO输出控制函数 GPIO_SetBits&#xff1a;将指定的GPIO引脚设置为高电平 GPIO_SetBits(GPIOA, GPIO_Pin_0); // 将GPIO…...

MySQL的不同SQL模式导致行为不同?

现象&#xff1a; 我在两个mysql库都有相同定义的表&#xff0c;其中一个字段是varchar(1200)。当我都对这个表进行insert操作&#xff0c;而且超过此字段的规定长度&#xff08;此处是1200&#xff09;&#xff0c;这两库的行为是不一样的&#xff1a;库B是直接报错too long&…...

Flink 使用 Kafka 作为数据源时遇到了偏移量提交失败的问题

具体的错误日志 21:43:57.069 [Kafka Fetcher for Source: Custom Source -> Map -> Filter (1/1)#2] ERROR org.apache.kafka.clients.consumer.internals.ConsumerCoordinator - [Consumer clientIdconsumer-my-group-6, groupIdmy-group] Offset commit failed on pa…...

【日志篇】(7.6) ❀ 01. 在macOS下刷新FortiAnalyzer固件 ❀ FortiAnalyzer 日志分析

【简介】FortiAnalyzer 是 Fortinet Security Fabric 安全架构的基础&#xff0c;提供集中日志记录和分析&#xff0c;以及端到端可见性。因此&#xff0c;分析师可以更有效地管理安全状态&#xff0c;将安全流程自动化&#xff0c;并快速响应威胁。具有分析和自动化功能的集成…...

地震勘探——干扰波识别、井中地震时距曲线特点

目录 干扰波识别反射波地震勘探的干扰波 井中地震时距曲线特点 干扰波识别 有效波&#xff1a;可以用来解决所提出的地质任务的波&#xff1b;干扰波&#xff1a;所有妨碍辨认、追踪有效波的其他波。 地震勘探中&#xff0c;有效波和干扰波是相对的。例如&#xff0c;在反射波…...

pam_env.so模块配置解析

在PAM&#xff08;Pluggable Authentication Modules&#xff09;配置中&#xff0c; /etc/pam.d/su 文件相关配置含义如下&#xff1a; 配置解析 auth required pam_env.so1. 字段分解 字段值说明模块类型auth认证类模块&#xff0c;负责验证用户身份&am…...

ETLCloud可能遇到的问题有哪些?常见坑位解析

数据集成平台ETLCloud&#xff0c;主要用于支持数据的抽取&#xff08;Extract&#xff09;、转换&#xff08;Transform&#xff09;和加载&#xff08;Load&#xff09;过程。提供了一个简洁直观的界面&#xff0c;以便用户可以在不同的数据源之间轻松地进行数据迁移和转换。…...

C++八股 —— 单例模式

文章目录 1. 基本概念2. 设计要点3. 实现方式4. 详解懒汉模式 1. 基本概念 线程安全&#xff08;Thread Safety&#xff09; 线程安全是指在多线程环境下&#xff0c;某个函数、类或代码片段能够被多个线程同时调用时&#xff0c;仍能保证数据的一致性和逻辑的正确性&#xf…...

打手机检测算法AI智能分析网关V4守护公共/工业/医疗等多场景安全应用

一、方案背景​ 在现代生产与生活场景中&#xff0c;如工厂高危作业区、医院手术室、公共场景等&#xff0c;人员违规打手机的行为潜藏着巨大风险。传统依靠人工巡查的监管方式&#xff0c;存在效率低、覆盖面不足、判断主观性强等问题&#xff0c;难以满足对人员打手机行为精…...

【Linux系统】Linux环境变量:系统配置的隐形指挥官

。# Linux系列 文章目录 前言一、环境变量的概念二、常见的环境变量三、环境变量特点及其相关指令3.1 环境变量的全局性3.2、环境变量的生命周期 四、环境变量的组织方式五、C语言对环境变量的操作5.1 设置环境变量&#xff1a;setenv5.2 删除环境变量:unsetenv5.3 遍历所有环境…...

JUC并发编程(二)Monitor/自旋/轻量级/锁膨胀/wait/notify/锁消除

目录 一 基础 1 概念 2 卖票问题 3 转账问题 二 锁机制与优化策略 0 Monitor 1 轻量级锁 2 锁膨胀 3 自旋 4 偏向锁 5 锁消除 6 wait /notify 7 sleep与wait的对比 8 join原理 一 基础 1 概念 临界区 一段代码块内如果存在对共享资源的多线程读写操作&#xf…...

Python爬虫(四):PyQuery 框架

PyQuery 框架详解与对比 BeautifulSoup 第一部分&#xff1a;PyQuery 框架介绍 1. PyQuery 是什么&#xff1f; PyQuery 是一个 Python 的 HTML/XML 解析库&#xff0c;它采用了 jQuery 的语法风格&#xff0c;让开发者能够用类似前端 jQuery 的方式处理文档解析。它的核心特…...

本地部署drawDB结合内网穿透技术实现数据库远程管控方案

文章目录 前言1. Windows本地部署DrawDB2. 安装Cpolar内网穿透3. 实现公网访问DrawDB4. 固定DrawDB公网地址 前言 在数字化浪潮席卷全球的背景下&#xff0c;数据治理能力正日益成为构建现代企业核心竞争力的关键因素。无论是全球500强企业的数据中枢系统&#xff0c;还是初创…...

docker容器互联

1.docker可以通过网路访问 2.docker允许映射容器内应用的服务端口到本地宿主主机 3.互联机制实现多个容器间通过容器名来快速访问 一 、端口映射实现容器访问 1.从外部访问容器应用 我们先把之前的删掉吧&#xff08;如果不删的话&#xff0c;容器就提不起来&#xff0c;因…...