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

news2024/10/28 21:06:59

目录

异常处理与调试:如何编写稳健的代码(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 / b
        print(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 = -5
    if 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 + b

result = 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.5

print(square_root(9))   # 输出 3.0
print(square_root(-1))  # 抛出 AssertionError: 输入必须为非负数

使用 pdb 进行交互式调试

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

示例:使用 pdb 调试
import pdb

def divide(a, b):
    pdb.set_trace()  # 设置断点
    return a / b

result = 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 num
        except 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 requests

def fetch_data(url):
    try:
        response = requests.get(url)
        response.raise_for_status()  # 检查请求是否成功
        data = response.json()
        return data
    except 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.coloradmin.cn/o/2225690.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

智能融合:国际数字影像产业园的数字化转型之路践

国际数字影像产业园作为数字园区的典型代表&#xff0c;在现代城市与企业发展进程中扮演着至关重要的角色。它深度融合了信息技术、物联网、大数据等一系列先进技术&#xff0c;全力聚焦于提升城市及企业的智能化水准与管理效能。 产业园围绕数字影像这一特定主题&#xff0c;…

基于KV260的基础视频链路通路(MIPI+Demosaic+VDMA)

目录 1. 简介 1.1 要点 1.2 背景 1.2.1 Got stuck 1.2.2 Cant be Initialized 2. Overlay 2.1 参考 Overlay 2.1.1 KV260 Base 2.1.2 Pynq-CV-OV5640 2.2 自建 Overlay 2.2.1 IIC IP 2.2.2 MIPI CSI-2 Rx 2.2.3 AXI4-S Subset 2.2.4 Demosaic 2.2.5 Pixel Pack …

【MySQL 保姆级教学】内置函数(9)

内置函数 1. 日期函数1.1 日期函数的种类1.2 示例1.3 日期的转换 2. 字符串函数2.1 种类2.2 示例 3. 数学函数3.1 种类3.2 向上取整和向下取整3.3 示例 4. 其他函数4.1 查询当前用户/数据库4.2 ifnull(val1,val2)4.3 md5()函数4.4 password()函数 1. 日期函数 1.1 日期函数的种…

Python | Leetcode Python题解之第514题自由之路

题目&#xff1a; 题解&#xff1a; Test "godding" target "d"i 0left i lc 0 right i rc 0while Test[left] ! target:left - 1lc 1if left -1:left len(Test) - 1while Test[right] ! target:right 1rc 1if right len(Test):right 0prin…

我用自研引擎做游戏:《干得好,托尼》

最近心里突然有个想法&#xff0c;想做一个游戏试试看。但是我从未做过游戏&#xff0c;这可咋办&#xff1f;我理性的思考了片刻&#xff0c;清楚的意识到&#xff0c;我要习得做游戏的方法论。于是到网上找了几本开发游戏的电子书&#xff0c;看了几天&#xff0c;就开始进入…

滚珠花键精密结构如何驱动旋转运动?

滚珠花键作为一种机械传动装置&#xff0c;具有升降旋转机构的功能&#xff0c;被广泛应用于各种机器设备中。那么&#xff0c;大家知道滚珠花键是如何实现旋转运动的吗&#xff1f; 滚珠花键实现旋转运动的工作原理可以概括为滚动摩擦和轴向移动与径向传动这两点&#xff0c;当…

TMGM平台可靠么?交易是否安全?

在选择外汇交易平台时&#xff0c;安全性与可靠性是投资者最关注的要素之一。作为全球知名的外汇及差价合约交易平台&#xff0c;TMGM&#xff08;tmgm-pt.com&#xff09;的安全性与可靠性可以从多个方面进行评估&#xff0c;包括监管环境、资金安全、客户服务、交易技术与服务…

Javascript数据结构——哈希表

18_哈希表_深入链地址法_哔哩哔哩_bilibili Java [ 基础 ] HashMap详解 ✨_java hashmap-CSDN博客 哈希表&#xff08;Hash Table&#xff09;&#xff0c;又称为散列表&#xff0c;是一种通过哈希函数组织数据以实现快速访问的数据结构。下面将从其概述、底层实现和前端应用…

【题解】【分治】——黑白棋子的移动

【题解】【递归】——黑白棋子的移动 黑白棋子的移动题目描述输入格式输出格式输入输出样例输入 #1输出 #1 提示 1.题意解析2.AC代码 黑白棋子的移动 通往洛谷的传送门 题目描述 有 2 n 2n 2n 个棋子排成一行&#xff0c;开始为位置白子全部在左边&#xff0c;黑子全部在右…

2024 前端面试题!!! html css js相关

常见的块元素、行内元素以及行内块元素&#xff0c;三者有何不同&#xff1f;​​​​​​​ HTML、XML、XHTML它们之间有什么区别&#xff1f;​​​​​​​ DOCTYPE(⽂档类型) 的作⽤ Doctype是HTML5的文档声明&#xff0c;通过它可以告诉浏览器&#xff0c;使用哪一个HTM…

Vue学习笔记(八)

透传attribute "透传attribute"指的是传递给一个组件&#xff0c;却没有被改组件声明为props或emits的attribute或者v-on事件监听器。最常见的例子就是class、style和id。 当一个组件以单个元素为根作渲染时&#xff0c;透传的attribute会自动被添加到根元素上。 …

WSGI、uwsgi与uWSGI

WSGI、uwsgi与uWSGI WSGI (web server gateway interface 网络服务网关接口) 只能用于python&#xff0c;是一个接口标准协议&#xff0c;django、flask自带有uwsgi 是WSGI的通信协议uWSGI是实现了uwsgi协议和WSGI服务的web服务器 他们是为了将web服务器与web框架连接起来 N…

《MYSQL 实战45讲》深入浅出ORDER BY底层

慢查询日志这个路径下&#xff0c;但是打不开 内存临时表 现在有一个业务功能是从一个单词表里面随机选出3个单词出来 这个表有10000条数据。 select word from words order by rank() limit 3 使用执行计划查看结果&#xff1a; select_type是SIMPLE表示改查询不包含子查询…

USB Type-C 受电端取电快充协议芯片,支持PD+QC+FCP+SCP+AFC快充协议

前言 随着科技的飞速发展&#xff0c;电子设备对于快速充电的需求日益增加。为了满足这一需求&#xff0c;市场上涌现出了众多快充技术和产品。其中&#xff0c;XSP08Q诱骗取电芯片以其卓越的性能和广泛的应用场景&#xff0c;成为了快充领域的一颗璀璨明星。本文将对XSP08Q P…

边缘计算网关在储能领域的应用-天拓四方

随着全球能源结构的转型和智能电网的快速发展&#xff0c;储能技术已成为推动能源革命的关键技术之一。在储能系统中&#xff0c;边缘计算网关作为一种新型的网络设备&#xff0c;发挥着至关重要的作用。 一、边缘计算网关在储能领域的应用 1、实时监控与控制 储能系统是一个…

hf_transformers-Quantization

bitsandbytes BitSandbytes 是将模型量化为 8 位和 4 位的最简单选项。8 位量化将 FP16 中的异常值与 INT8 中的非异常值相乘&#xff0c;将非异常值转换回 FP16&#xff0c;然后将它们相加以返回 FP16 中的权重。这减少了离群值对模型性能的降级影响。4 位量化进一步压缩模型…

【小白学机器学习22】 多变量分析:相关性分析,多变量回归,最小二乘法 ols等

目录 1 概念名词&#xff1a; 1.1 双变量分析与单因素分析 1.2 变化 1.3 共变 和 相关分析 Correlation analysis 1.4 回归分析 Regression analysis 1.5 相干和相关 1.5.1 相干relevant 1.5.2 相关Correlation 2 双变量分析 3 相关分析 3.1 是否相关 3.2 相关的…

Ping32为何是理想的加密工具?十大核心功能保障您的数据安全

在当今数字化时代&#xff0c;数据安全已成为企业和个人面临的重大挑战。随着信息泄露事件的频繁发生&#xff0c;选择一款可靠的加密工具至关重要。Ping32 作为一款备受赞誉的加密软件&#xff0c;以其十大核心功能&#xff0c;成为保障数据安全的理想选择。 一、强大的加密算…

React第十一章(useReducer)

useReducer useReducer是React提供的一个高级Hook,没有它我们也可以正常开发&#xff0c;但是useReducer可以使我们的代码具有更好的可读性&#xff0c;可维护性。 useReducer 跟 useState 一样的都是帮我们管理组件的状态的&#xff0c;但是呢与useState不同的是 useReducer…

JsonCpp库学习记录

使用源码的方式 到JsonCpp的开源库仓库下载最新的发行版本 解压压缩包 使用Python生成源码文件 在本路径下cmd打开控制台&#xff0c;使用python编译&#xff08;前提是python环境已安装&#xff09; python amalgamate.py 生成dist文件夹 jsoncpp为整合在一起的源码&#…