异常处理与调试:如何编写稳健的代码(8/10)

目录

异常处理与调试:如何编写稳健的代码(8/10)

介绍

异常概述

常见的异常类型

使用 try...except 处理异常

基本结构

示例:读取文件内容

捕获多个异常

自定义异常

示例:自定义异常类

调试代码

使用 print() 调试

使用 assert 进行断言调试

使用 pdb 进行交互式调试

示例:使用 pdb 调试

编写健壮代码的原则

1. 使用异常处理

2. 输入验证

3. 使用 finally 进行资源清理

4. 避免捕获所有异常

综合示例:网络请求中的异常处理

总结


异常处理与调试:如何编写稳健的代码(8/10)

介绍

编写代码时,错误是不可避免的,因此有效地处理错误和调试代码是成为优秀开发者的重要技能。Python 提供了强大的异常处理机制,使得我们可以在程序出现错误时优雅地应对,而不会中断整个应用的运行。在本篇文章中,我们将详细讲解 Python 中的异常处理,如何使用调试工具,以及编写健壮代码的原则。通过学习这些内容,你将能够编写更稳健的程序,确保在面对各种异常情况时程序仍能正常运行。

异常概述

异常(Exception)是指在程序运行时发生的错误。例如,试图除以零或访问不存在的文件都会导致异常。Python 使用 try...except 语句来捕获和处理这些异常。

常见的异常类型

  • ZeroDivisionError:当除数为零时抛出。

  • FileNotFoundError:试图打开不存在的文件时抛出。

  • ValueError:传入的参数类型不正确时抛出。

  • KeyError:访问字典中不存在的键时抛出。

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

输出:

发生错误: division by zero

在上面的示例中,ZeroDivisionError 异常被捕获,程序不会因此崩溃,而是输出一条错误信息。

使用 try...except 处理异常

在 Python 中,try...except 语句用于捕获和处理异常。

基本结构

try:# 可能发生异常的代码
except ExceptionType as e:# 处理异常的代码
finally:# 无论是否发生异常,都会执行的代码
  • try 块中编写可能发生异常的代码。

  • except 块用于捕获异常,可以指定异常类型。

  • finally 块无论是否发生异常,都会执行,通常用于资源清理。

示例:读取文件内容

try:with open("data.txt", "r") as file:content = file.read()print(content)
except FileNotFoundError:print("文件未找到,请检查文件名。")
finally:print("操作结束。")

输出(假设文件不存在):

文件未找到,请检查文件名。
操作结束。

在上面的代码中,try 块用于尝试打开文件并读取内容。如果文件不存在,则会触发 FileNotFoundError,并由 except 块处理,最后无论是否发生异常,finally 块都会执行。

捕获多个异常

我们可以在 except 语句中捕获多个异常,并对每个异常分别处理。

def divide(a, b):try:result = a / bprint(f"结果是: {result}")except ZeroDivisionError:print("错误: 除数不能为零。")except TypeError:print("错误: 参数类型不正确,请输入数字。")divide(10, 0)   # 捕获 ZeroDivisionError
divide(10, "a") # 捕获 TypeError

输出:

错误: 除数不能为零。
错误: 参数类型不正确,请输入数字。
异常类型描述示例
ZeroDivisionError除数为零时抛出10 / 0
FileNotFoundError文件不存在时抛出open("nofile.txt", "r")
ValueError传入参数类型不正确时抛出int("abc")
KeyError字典中不存在的键时抛出my_dict["nonexistent_key"]

自定义异常

在某些情况下,我们可能希望自定义异常,以便对特定的业务逻辑进行更精细的控制。可以通过继承 Exception 类来创建自定义异常。

示例:自定义异常类

class NegativeNumberError(Exception):"""自定义异常类,用于处理负数输入"""def __init__(self, value):super().__init__(f"错误: 不允许的负数输入: {value}")# 使用自定义异常
try:number = -5if number < 0:raise NegativeNumberError(number)
except NegativeNumberError as e:print(e)

输出:

错误: 不允许的负数输入: -5

调试代码

调试代码是找出和修复错误的重要步骤。Python 提供了多种调试工具,包括 print() 调试、assert 语句和 pdb 调试器。

使用 print() 调试

print() 是最简单的调试方法,通过在代码的不同位置打印变量的值,帮助我们找到错误发生的位置。

def add_numbers(a, b):print(f"a = {a}, b = {b}")  # 打印变量的值return a + bresult = add_numbers(5, 3)
print(f"结果: {result}")

输出:

a = 5, b = 3
结果: 8

使用 assert 进行断言调试

assert 语句用于检查条件是否为真,如果为假则抛出 AssertionError 异常,通常用于测试代码中的假设是否正确。

def square_root(x):assert x >= 0, "输入必须为非负数"return x ** 0.5print(square_root(9))   # 输出 3.0
print(square_root(-1))  # 抛出 AssertionError: 输入必须为非负数

使用 pdb 进行交互式调试

pdb 是 Python 的内置调试器,可以逐行执行代码,检查变量的值,帮助找出错误的根源。

示例:使用 pdb 调试
import pdbdef divide(a, b):pdb.set_trace()  # 设置断点return a / bresult = divide(10, 2)
print(f"结果: {result}")

当执行到 pdb.set_trace() 时,程序会暂停,进入调试模式。可以使用 n 命令执行下一行代码,p 命令查看变量值。

调试工具描述示例
print()打印变量值,简单易用print(f"变量值: {var}")
assert检查条件是否为真,调试假设assert x > 0, "x 必须为正数"
pdb交互式调试器,逐行执行代码pdb.set_trace()

编写健壮代码的原则

编写健壮代码可以让程序在面对各种异常情况时仍然保持稳定。以下是一些编写健壮代码的原则:

1. 使用异常处理

确保程序中的关键操作都包含异常处理,例如文件操作、网络请求等。

try:with open("data.txt", "r") as file:content = file.read()
except FileNotFoundError:print("文件未找到,请检查文件名。")

2. 输入验证

在处理用户输入时,必须验证输入的有效性,防止意外错误。

def get_positive_number():while True:try:num = int(input("请输入一个正整数: "))if num <= 0:raise ValueError("输入必须为正整数。")return numexcept ValueError as e:print(e)

3. 使用 finally 进行资源清理

在操作文件或网络连接等资源时,使用 finally 确保资源被正确关闭。

try:file = open("data.txt", "r")# 执行文件操作
finally:file.close()  # 确保文件被正确关闭

4. 避免捕获所有异常

捕获所有异常(如 except Exception:)可能会隐藏真正的问题。应尽量捕获特定的异常类型,以便更好地调试。

try:# 可能发生异常的代码
except ZeroDivisionError:print("除数不能为零。")
except ValueError:print("输入值错误。")

综合示例:网络请求中的异常处理

在本示例中,我们将演示如何处理网络请求中的各种异常情况,以确保程序的健壮性。

import requestsdef fetch_data(url):try:response = requests.get(url)response.raise_for_status()  # 检查请求是否成功data = response.json()return dataexcept requests.exceptions.HTTPError as http_err:print(f"HTTP 错误: {http_err}")except requests.exceptions.ConnectionError:print("连接错误,请检查网络。")except requests.exceptions.Timeout:print("请求超时,请重试。")except requests.exceptions.RequestException as err:print(f"请求错误: {err}")# 测试网络请求
data = fetch_data("https://jsonplaceholder.typicode.com/posts/1")
if data:print("数据:", data)

在这个示例中,我们对网络请求的各种可能异常进行了处理,包括 HTTP 错误、连接错误、超时等,确保程序不会因为请求失败而崩溃。

总结

在本篇文章中,我们学习了 Python 中的异常处理机制,包括如何使用 try...except 捕获异常、自定义异常以及调试代码的方法。我们还介绍了编写健壮代码的原则,使得程序在面对各种异常情况时仍能稳定运行。掌握这些技能后,你将能够编写更加稳健和可维护的代码。

在下一篇文章中,我们将讨论数据处理与可视化,学习如何使用 Python 的 pandasmatplotlib 库进行数据分析和可视化。敬请期待!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/458839.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

AI跟踪报道第62期-本周AI新闻: 微软推出Copilot的AI Agent和Computer Control

每周跟踪AI热点新闻动向和震撼发展 想要探索生成式人工智能的前沿进展吗&#xff1f;订阅我们的简报&#xff0c;深入解析最新的技术突破、实际应用案例和未来的趋势。与全球数同行一同&#xff0c;从行业内部的深度分析和实用指南中受益。不要错过这个机会&#xff0c;成为AI领…

重写(外壳不变)

重写&#xff1a;是子类对父类非静态、非private修饰、非final修饰、非构造方法等的实现过程进行重新编写返回值和形参都不能改变。 重写的好处&#xff1a;子类可以根据需要&#xff0c;定义专属于自己的行为。&#xff08;子类能够根据需要实现父类的方法&#xff09; 方法…

封装echarts组件,即插即用(附源码)

前言&#xff1a;最近一个项目刚收工&#xff0c;分享一个常用的封装echarts的组件。 一、直接上组件代码 <template><el-card class"echart-card" shadow"hover"><template v-slot:header><div class"card-header">&…

JS面试八股文(三)

&#x1f60a;文章目录 21.说一下事件循环22.ajax是什么&#xff1f;怎么实现&#xff1f;23.get和post有什么区别&#xff1f;24.Promise的内部原理是什么&#xff1f;它的缺点是什么&#xff1f;25.Promise和async await的区别是什么&#xff1f;26.浏览器的存储方式有哪些&a…

python实战(二)——房屋价格回归建模

一、任务背景 本章将使用一个经典的Kaggle数据集——House Prices - Advanced Regression Techniques进行回归建模的讲解。这是一个房价数据集&#xff0c;与我们熟知的波士顿房价数据集类似&#xff0c;但是特征数量要更多&#xff0c;数据也要更为复杂一些。下面&#xff0c;…

Linux 命令行查看当前目录的总大小/总磁盘空间/磁盘清理

一、du 查看目录空间大小 &#xff08;一&#xff09; du 命令解析 在Linux命令行可以使用 du 命令来查看当前目录的总大小。du 是 disk usage 的缩写&#xff0c;表示磁盘使用情况。 命令解释&#xff1a;总结每个文件的磁盘使用情况&#xff0c;递归地用于目录。 使用格式…

以通俗易懂的仓库来讲解JVM内存模型

JVM内存模型可以想象成一个大型的仓库&#xff0c;这个仓库被分成了几个不同的区域&#xff0c;每个区域都有特定的用途和规则。下面我们用一个仓库的比喻来介绍JVM内存模型&#xff1a; 仓库大门&#xff08;JVM启动&#xff09;&#xff1a; 当JVM启动时&#xff0c;就像打开…

自动化抖音点赞取消脚本批量处理

&#x1f31f; 前言 欢迎来到我的技术小宇宙&#xff01;&#x1f30c; 这里不仅是我记录技术点滴的后花园&#xff0c;也是我分享学习心得和项目经验的乐园。&#x1f4da; 无论你是技术小白还是资深大牛&#xff0c;这里总有一些内容能触动你的好奇心。&#x1f50d; &#x…

多个立方体盒子组成

效果&#xff1a; 知识了解&#xff1a; 在同一水平上&#xff0c;盒子经纬度计算&#xff1a;经度有误差&#xff0c;纬度没有误差 纬度计算&#xff1a;lat50/111320 约等于0.000449 经度计算&#xff1a;lon50/111320*cos(纬度) 约等于0.000519 一个立方体&#xff1a; // 添…

CentOS进入单用户模式进行密码重置

一、单用户模式介绍 单用户模式是一种特殊的启动模式&#xff0c;主要用于系统维护和故障排除。在单用户模式下&#xff0c;系统以最小化的状态启动&#xff0c;只有最基本的系统服务会被加载&#xff0c;通常只有root用户可以登录。这种模式提供了对系统的完全控制&#xff0…

模型训练识别手写数字(一)

一、模型训练数据集 1. 导入所需库 import numpy as np from sklearn.datasets import fetch_openmlnumpy 是用于数值计算的库。 fetch_openml 是用于从 OpenML 下载数据集的函数。 2. 获取 MNIST 数据集 X, y fetch_openml(mnist_784, version1, return_X_yTrue)fetch_ope…

Spring Boot与Flyway实现自动化数据库版本控制

一、为什么使用Flyway 最简单的一个项目是一个软件连接到一个数据库&#xff0c;但是大多数项目中我们不仅要处理我们开发环境的副本&#xff0c;还需要处理其他很多副本。例如&#xff1a;开发环境、测试环境、生产环境。想到数据库管理&#xff0c;我们立刻就能想到一系列问…

Ovis原理解读: 多模态大语言模型的结构嵌入对齐

论文&#xff1a;https://arxiv.org/pdf/2405.20797 github:https://github.com/AIDC-AI/Ovis 在多模态大语言模型 (MLLM) 中&#xff0c;不同的嵌入策略有显著的区别。以下是使用基于连接器的方法与 Ovis 方法的比较&#xff1a; 基于连接器的方法-优缺点(connector-based …

斜杠往哪斜、路径绝对还是相对,终端目录切换不再迷茫

目录 路径表示绝对路径相对路径两者区别 路径中斜杠的用法正反斜杠对比表一个常见的问题 终端切换目录常用cd指令同一盘符内跨盘符 路径表示 在计算机文件系统中&#xff0c;路径是用来指定文件或目录位置的一种方式。路径可以是绝对路径或相对路径&#xff1a; 绝对路径 绝…

cmake 编译 vtk

1. 下载 VTK 源码 vtk 源码&#xff0c;点击&#xff1a;官网下载 在官网选择合适的版本下载&#xff0c;这里下载的是 vtk 8.2.0 版本 2. 下载 CMake CMake 工具&#xff0c;点击&#xff1a;镜像下载 下载版本比较新的 CMake 版本&#xff0c;这里使用的是 CMake 3.29.2 版…

在不支持AVX的linux上使用PaddleOCR

背景 公司的虚拟机CPU居然不支持avx, 默认的paddlepaddle的cpu版本又需要有支持avx才行,还想用PaddleOCR有啥办法呢? 是否支持avx lscpu | grep avx 支持avx的话,会显示相关信息 如果不支持的话,python运行时导入paddle会报错 怎么办呢 方案一 找公司it,看看虚拟机为什么…

C++基础:constexpr,类型转换和选择语句

constexpr 提到constexpr&#xff0c;我们会发现它和const类比 常和const类比constexpr符号常量必须给定一个在编译时已知的值&#xff0c; 若某个变量初始化时的值在编译时未知&#xff0c;但初始化后绝不变。 #include<iostream> #include<vector> #include&l…

【机器学习基础】激活函数

激活函数 1. Sigmoid函数2. Tanh&#xff08;双曲正切&#xff09;函数3. ReLU函数4. Leaky ReLU函数 1. Sigmoid函数 观察导数图像在我们深度学习里面&#xff0c;导数是为了求参数W和B&#xff0c;W和B是在我们模型model确定之后&#xff0c;找出一组最优的W和B&#xff0c;使…

Go使用exec.Command() 执行脚本时出现:file or directory not found

使用 Go 提供的 exec.Command() 执行脚本时出现了未找到脚本的 bug&#xff0c;三个排查思路 &#xff1a; exec.Command(execName, args…) 脚本名字不允许相对路径 exec.Command(execName, args…) execName 只能有脚本名&#xff0c;不允许出现参数 如果你是使用 Windows …

Python爬虫:商品详情的“八卦记者”

亲爱的代码侦探们&#xff0c;今天咱们不聊那些让人头秃的bug&#xff0c;也不谈那些让人眼花的架构图。咱们来聊聊那些在代码世界里挖掘商品秘密的“八卦记者”——Python爬虫。 Python爬虫&#xff1a;商品详情的“八卦记者” 想象一下&#xff0c;你在代码的世界里&#xf…