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

Python异常处理:三种不同方法的探索与最佳实践

在这里插入图片描述

Python异常处理:三种不同方法的探索与最佳实践

前言

本文旨在探讨Python中三种不同的异常处理方法。通过深入理解各种异常处理策略,我们可以更好地应对不同的编程场景,选择最适合自己需求的方法。

异常处理在编程中扮演着至关重要的角色。合适的异常处理不仅可以提高代码的健壮性,还能增强程序的可读性和可维护性。在Python编程中,有效地管理异常是提高代码质量的关键一环。

在开始深入探讨之前,让我们先通过一个实际的编程难题来引入这个话题:


前天,一位朋友向我提出了一个问题。在处理一个循环遍历时,由于难以预见所有可能的错误,他需要为每个循环中的元素实现异常处理,以防某个元素的错误影响到整个程序的运行。

但这样做的结果是,代码因为过多的 try-except 块而变得冗长且难以维护。这种情况下,我们怎样才能优化代码,既处理异常又保持代码的清晰和简洁呢?

示例代码如下:

for item in html_xpath:try:try:url = item.xpath('//title/url-ellipsis/a/url()')except Exception as e:url = Nonetry:title = item.xpath('//title/text-ellipsis/a/text()')except Exception as e:title = None...except Exception as e:...

在本文中,我们将探讨三种不同的异常处理方法,并在最后回到这个问题,提供一个优化后的解决方案。


知识点📖📖

查阅这两篇文章,对食用本文更有帮助哦!!

  • 深入浅出Python异常处理 - 你所不知道的Python异常

  • 万字长文 - Python 日志记录器logging 百科全书 之 基础配置

在这里先总结下文中会介绍到的三种异常处理方法的优缺点以及应用场景:

方法优点缺点应用场景
try-except简单直接,易于理解。
针对不同类型的异常可以编写特定处理逻辑。
代码中频繁使用会导致代码冗长适用于处理已知可能发生的错误。
用于具体函数或代码块中的错误处理。
sys.excepthook全局捕获未处理的异常。
使用相对简单。
不能阻止程序因异常而终止。
仅处理未被 try-except 块捕获的异常。
在子线程中不适用。
适用于记录未捕获的异常。
错误报告和日志记录。
装饰器提高代码复用性和清晰度。
可定制化异常处理逻辑。
使用和理解需要更高的Python技能水平。
只适用于被装饰的函数。
适用于需要统一异常处理逻辑的函数。
用于减少代码重复,提高维护性。

异常处理方法总结✨✨

Python中有多种方式来处理异常,每种方法都适用于不同的情况和需求。

通过选择适当的异常处理方法,我们可以更好地管理和处理Python程序中的异常情况。

以下是三种常见的异常处理方法以及它们的优点和缺点:

1. 使用 try-except 块

优点:简单直接,易于理解;允许针对不同类型的异常编写特定的处理逻辑。

缺点:在代码中频繁重复使用可能导致代码冗长。

示例代码:

try:# 可能会引发异常的代码result = 1 / 0
except ZeroDivisionError:# 处理特定类型的异常print("不能除以零")

代码释义:

代码使用了 try-except 块来捕获特定类型的异常(ZeroDivisionError),且打印了一条错误消息。

代码运行效果如下:

在这里插入图片描述

2. 使用 sys.excepthook

sys.excepthookPython中的一个全局函数,它在脚本遇到未捕获的异常时被调用。默认情况下,当一个异常没有被任何 try-except 块捕获时,Python会调用 sys.excepthook,打印出异常信息以及堆栈跟踪。

优点:允许在程序的任何地方捕获未被处理的异常;使用起来相对简单。

缺点:不能阻止程序因未处理的异常而终止;只能用于处理未被 try-except 块捕获的异常。

示例代码:

import sysdef global_exception_handler(exc_type, exc_value, exc_traceback):print("完犊子咯!这里捕获了异常:", exc_value)sys.excepthook = global_exception_handler# 示例:故意制造一个除以零的错误
result = 1 / 0
print('没运行到这里哦!')

代码释义:

代码配置了 sys.excepthook,使其在未捕获的异常发生时,会调用 global_exception_handler 函数来处理异常。

它允许在程序的任何地方捕获未被处理的异常,但在捕获了未经处理的异常后程序会终止(优雅的退出。)

代码运行效果如下:

  • 可以看到,代码并没有运行到 print('没运行到这里哦!') 这一行~
    在这里插入图片描述

3. 使用装饰器

优点:提高代码的复用性和清晰度,减少重复代码;可以定制化异常处理逻辑,应用于特定的函数。

缺点:相较于直接的 try-except 块,装饰器的使用和理解需要更高的Python技能水平;只适用于被装饰的函数。

示例代码:

def catch_exceptions(func):def wrapper(*args, **kwargs):try:return func(*args, **kwargs)except Exception as e:print(f"Exception caught in {func.__name__}: {e}")return Nonereturn wrapper@catch_exceptions
def risky_function(x, y):return x / yresult = risky_function(1, 0)
print("程序继续执行")

代码释义:

代码定义了一个装饰器 catch_exceptions,它可以应用于所有需要处理的函数。当被装饰的函数抛出异常时,装饰器会捕获异常并打印错误消息。

代码运行效果如下:

  • 可以看到,程序在捕获了异常后,还可以正常向下执行~
    在这里插入图片描述

4. 更健壮的代码

这份代码在 使用装饰器 的基础上添加了堆栈打印和日志记录,而日志记录的作用,想必大家都很清楚了。

关于日志记录的使用,可以查阅俺前面的文章。

import logging
import traceback
import sys# 配置日志记录器
logging.basicConfig(filename='app.log',level=logging.DEBUG,format='%(asctime)s - %(levelname)s - %(message)s',encoding='utf-8',filemode='w'
)def catch_exceptions(func):def wrapper(*args, **kwargs):try:return func(*args, **kwargs)except Exception as e:exc_type, exc_value, exc_traceback = sys.exc_info()# 将异常信息记录到日志logging.error(f"Exception caught in {func.__name__}: {e}")logging.error(f"Exception type: {exc_type}")logging.error(f"Exception value: {exc_value}")log_traceback = ''.join(traceback.format_tb(exc_traceback))logging.error(f"Exception traceback: {log_traceback}")return Nonereturn wrapper@catch_exceptions
def risky_function(x, y):return x / y  # 这里可能会引发 ZeroDivisionErrorresult = risky_function(1, 0)
print("程序继续执行")

代码运行效果如下:

  • 可以看到,日志记录的信息非常清晰。

在这里插入图片描述

解决前面的问题

这份代码解决了前面的问题,nice~

在这份代码中,我特地模拟了一段html文本,然后在 xpath_expression中特地使用了错误的表达式。
因代码只用作于演示,所以这里不添加日志记录和对战堆栈了~~

from lxml import html# 定义异常处理装饰器
def catch_exceptions(func):def wrapper(*args, **kwargs):try:return func(*args, **kwargs)except Exception as e:print(f"Exception caught in {func.__name__}: {e}")return '空'return wrapper# 使用装饰器来解析HTML元素
@catch_exceptions
def parse_element(sub_element, xpath_expression):return sub_element.xpath(xpath_expression)# 示例HTML元素
item_html = """
<div><a href="https://frica.blog.csdn.net/?type=blog">frica Link</a><span>是小菜欸</span>...
</div>
"""# 定义HTML元素与XPath的映射
html_xpath_map = {'url': "//a/@href",'title': "//span/text()",'other': '//dd/dd/ddd/text()','age': '这不是xpath_expression表达式'
}if __name__ == '__main__':result_map = dict()# 创建HTML元素对象element = html.fromstring(item_html)# 遍历XPath映射,解析元素并将结果存入字典for key, value in html_xpath_map.items():result = parse_element(element, value)result_map[key] = result[0] if result else '空'# 海象运算符# result_map[key] = x[0] if (x := parse_element(element, value)) else '空'# 打印解析结果print(result_map)

代码释义:

这份代码的主要目的是解决在循环遍历中处理异常的问题,

通过使用装饰器和Xpath来简化异常处理,并使代码更清晰和简洁。

总的来说,这份关于异常处理的代码已经很健壮了!!

看不懂的读者朋友们回去阅读我前面的文章~~

代码运行效果:

在这里插入图片描述

总结

Python中,不同的异常处理方法适用于不同的场景。

  • 使用 try-except 块适用于处理已知可能发生的错误,适用于具体函数或代码块中的错误处理。
  • sys.excepthook 适用于记录未捕获的异常,用于错误报告和日志记录,但不能阻止程序终止。
  • 装饰器适用于需要统一异常处理逻辑的函数,提高代码的复用性和清晰度。

在选择异常处理方法时,应根据具体需求和项目背景考虑使用哪种方法,并根据最佳实践和注意事项来编写异常处理代码,以确保代码的健壮性和可维护性。

后话

本次分享到此结束,

see you~🐱‍🏍🐱‍🏍

相关文章:

Python异常处理:三种不同方法的探索与最佳实践

Python异常处理&#xff1a;三种不同方法的探索与最佳实践 前言 本文旨在探讨Python中三种不同的异常处理方法。通过深入理解各种异常处理策略&#xff0c;我们可以更好地应对不同的编程场景&#xff0c;选择最适合自己需求的方法。 异常处理在编程中扮演着至关重要的角色。合…...

一文图解爬虫(spider)

—引导语 互联网&#xff08;Internet&#xff09;进化到今天&#xff0c;已然成为爬虫&#xff08;Spider&#xff09;编制的天下。从个体升级为组合、从组合联结为网络。因为有爬虫&#xff0c;我们可以更迅速地触达新鲜“网事”。 那么爬虫究竟如何工作的呢&#xff1f;允许…...

腾讯云3年期轻量应用服务器优惠(薅羊毛教程)

腾讯云轻量应用服务器特价是有新用户限制的&#xff0c;所以阿腾云建议大家选择3年期轻量应用服务器&#xff0c;一劳永逸&#xff0c;免去续费困扰。腾讯云轻量应用服务器3年优惠可以选择2核2G4M和2核4G5M带宽&#xff0c;3年轻量2核2G4M服务器540元&#xff0c;2核4G5M轻量应…...

多个div横向排列的几种方法

以下面这组 div 为例&#xff0c;group的高度由内容撑开 <div id"group"><div id"div1">div1</div><div id"div2">div2</div><div id"div3">div3</div> </div>显示结果如下为上下排…...

【编程语言发展史】Go语言的发展历史

目录 Go的起源 Go语言发展时间轴 logo Go的起源 Go 语言起源 2007 年&#xff0c;并于 2009 年正式对外发布。它从 2009 年 9 月 21 日开始作为谷歌公司 20% 兼职项目&#xff0c;即相关员工利用 20% 的空余时间来参与 Go 语言的研发工作。该项目的三位领导者均是著名的 …...

深入理解JVM虚拟机第二十三篇:详解JVM当中的栈顶缓存技术

大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。 孙哥链接:孙哥个人主页 作者简介:一个颜值99分,只比孙哥差一点的程序员 本专栏简介:话不多说,让我们一起干翻JVM 本文章简介:话不多说,让我们讲清楚JVM当中与操作数栈相关的字节码指令…...

通过easyexcel导出数据到表格

这篇文章简单介绍一下怎么通过easyexcel做数据的导出&#xff0c;使用之前easyui构建的歌曲列表crud应用&#xff0c;添加一个导出按钮&#xff0c;点击的时候直接连接后端接口地址&#xff0c;在后端的接口完成数据的导出功能。 前端页面完整代码 let editingId; let request…...

C++入门学习(4)引用 (讲解拿指针比较)

上期回顾 在学习完函数重载之后&#xff0c;我们可以使用多个重名函数进行操作&#xff0c;会发现C真的是弥补了好多C语言的不足之处&#xff0c;真的不禁感概一下&#xff0c;时代的进步是需要人去做出改变的&#xff0c;而不是一味的使用啊&#xff01;所以我们今天继续学一下…...

温度采集DS18B20

/******************************************************************** * 描述 : 该文件实现了用温度传感器件DS18B20对温度的采集&#xff0c;并在数码管上显示出来。 ***********************************************************************/ #include<reg52.h&…...

同城跑腿服务预约小程序的作用如何

无论是互联网服务化加快还是前几年疫情冲击&#xff0c;在同城生活服务场景中出现了很多商机&#xff0c;如外卖跑腿、校园跑腿、代买代送等&#xff0c;无论公司还是个人都借势不断提升自己品牌的影响力&#xff0c;并且依赖朋友圈不断提升生意营收。 同城跑腿品牌不少&#…...

前后端开发迭代

要创建一个具有登录和注册功能的前端网页&#xff0c;并使用Go语言编写后端来支持它&#xff0c;你需要分两部分来进行&#xff1a;前端开发和后端开发。下面我将提供一个基本的指导方案。 前端开发 前端部分主要涉及HTML、CSS和JavaScript。你可以使用框架如React或Vue来简化…...

Git可视化界面的操作,SSH协议的以及IDEA集成Git

目录 一. Git可视化界面的操作 二. gitee的ssh key 2.1 SSH协议 2.2 ssh key 三. IDEA集成Git 3.1 分享项目 3.2 下载项目 一. Git可视化界面的操作 上一篇博客只用到了git的命令窗口&#xff0c;现在就来看看可视化窗口要怎么操作。 点击Git GUI Here GUI界面 在g…...

CSS的初步学习

CSS 层叠样式表 (Cascading Style Sheets). CSS 能够对网页中元素位置的排版进行像素级精确控制, 实现美化页面的效果. 能够做到页面的样式和结 构分离. CSS 就是 “东方四大邪术” 之化妆术 CSS 基本语法规范: 选择器 若干属性声明 选择器决定针对谁修改 (找谁) 声明决定修…...

小程序样式问题

小程序切换下一个文章或者页面&#xff0c;淡入淡出效果 // detail.js getArticleData: function(articleId) {// 开始淡出效果this.animate(.detail-page, [{ opacity: 1.0, ease: ease-out },{ opacity: 0.0, ease: ease-out }], 500, () > {// 在淡出动画完成后请求文章…...

大数据毕业设计选题推荐-生产大数据平台-Hadoop-Spark-Hive

✨作者主页&#xff1a;IT毕设梦工厂✨ 个人简介&#xff1a;曾从事计算机专业培训教学&#xff0c;擅长Java、Python、微信小程序、Golang、安卓Android等项目实战。接项目定制开发、代码讲解、答辩教学、文档编写、降重等。 ☑文末获取源码☑ 精彩专栏推荐⬇⬇⬇ Java项目 Py…...

什么是Ribbon的饥饿加载?有什么优势?

目录 一、什么是Ribbon 二、什么是饥饿加载 三、Ribbon饥饿加载的优势 四、Ribbon饥饿加载的劣势 一、什么是Ribbon Ribbon是一个开源的、基于HTTP和TCP的客户端负载均衡工具&#xff0c;它提供了一个简单的、基于配置的负载均衡策略&#xff0c;可以帮助开发人员更轻松地…...

苹果手机安装未上架APP应用测试教程

STEP 2&#xff1a;找到下载的描述文件&#xff08;如果没有找到&#xff0c;请到 设置 - 通用 - 描述文件 中查看&#xff09; STEP 3&#xff1a;安装描述文件 STEP 4&#xff1a;输入解锁密码安装描述文件 STEP 5&#xff1a;同意免责声明&#xff0c;安装描述文件 STEP 6…...

asp.net core自定义授权过滤器

1.记录点击页面的地址&#xff0c;如果点击页面时未登录&#xff0c;直接跳转到登录页面&#xff0c;登录后直接跳转到自己点击的页面 2.创建授权过滤器 using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Mvc.Filters; using System.Web;namespace Log4NetTest {/…...

SW如何显示样条曲线的控标

刚刚学习隔壁老王的sw画图时&#xff0c;怎么点都点不出样条曲线的控标&#xff0c;于是果断查询了一下解决方法&#xff0c;其实很简单&#xff0c;只不过是培训机构故意不说&#xff0c;叫你还解决不了&#xff0c;难受了就会花钱买他们的课了。毕竟如果学会了怎么解决问题了…...

CSS 的 link 标签放在 head 标签之间的作用

当我们在开发网页时&#xff0c;经常会遇到关于CSS文件引入位置的讨论。有些人喜欢将CSS文件的链接放在HTML文件的底部&#xff0c;而另一些人则认为最好将CSS链接放在<head>标签之间。那么&#xff0c;究竟应该将CSS的link标签放在head标签之间的原因是什么呢&#xff1…...

Golang 面试经典题:map 的 key 可以是什么类型?哪些不可以?

Golang 面试经典题&#xff1a;map 的 key 可以是什么类型&#xff1f;哪些不可以&#xff1f; 在 Golang 的面试中&#xff0c;map 类型的使用是一个常见的考点&#xff0c;其中对 key 类型的合法性 是一道常被提及的基础却很容易被忽视的问题。本文将带你深入理解 Golang 中…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

Qwen3-Embedding-0.6B深度解析:多语言语义检索的轻量级利器

第一章 引言&#xff1a;语义表示的新时代挑战与Qwen3的破局之路 1.1 文本嵌入的核心价值与技术演进 在人工智能领域&#xff0c;文本嵌入技术如同连接自然语言与机器理解的“神经突触”——它将人类语言转化为计算机可计算的语义向量&#xff0c;支撑着搜索引擎、推荐系统、…...

【HTML-16】深入理解HTML中的块元素与行内元素

HTML元素根据其显示特性可以分为两大类&#xff1a;块元素(Block-level Elements)和行内元素(Inline Elements)。理解这两者的区别对于构建良好的网页布局至关重要。本文将全面解析这两种元素的特性、区别以及实际应用场景。 1. 块元素(Block-level Elements) 1.1 基本特性 …...

Redis数据倾斜问题解决

Redis 数据倾斜问题解析与解决方案 什么是 Redis 数据倾斜 Redis 数据倾斜指的是在 Redis 集群中&#xff0c;部分节点存储的数据量或访问量远高于其他节点&#xff0c;导致这些节点负载过高&#xff0c;影响整体性能。 数据倾斜的主要表现 部分节点内存使用率远高于其他节…...

基于Java Swing的电子通讯录设计与实现:附系统托盘功能代码详解

JAVASQL电子通讯录带系统托盘 一、系统概述 本电子通讯录系统采用Java Swing开发桌面应用&#xff0c;结合SQLite数据库实现联系人管理功能&#xff0c;并集成系统托盘功能提升用户体验。系统支持联系人的增删改查、分组管理、搜索过滤等功能&#xff0c;同时可以最小化到系统…...

VM虚拟机网络配置(ubuntu24桥接模式):配置静态IP

编辑-虚拟网络编辑器-更改设置 选择桥接模式&#xff0c;然后找到相应的网卡&#xff08;可以查看自己本机的网络连接&#xff09; windows连接的网络点击查看属性 编辑虚拟机设置更改网络配置&#xff0c;选择刚才配置的桥接模式 静态ip设置&#xff1a; 我用的ubuntu24桌…...

视觉slam十四讲实践部分记录——ch2、ch3

ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...

uniapp 小程序 学习(一)

利用Hbuilder 创建项目 运行到内置浏览器看效果 下载微信小程序 安装到Hbuilder 下载地址 &#xff1a;开发者工具默认安装 设置服务端口号 在Hbuilder中设置微信小程序 配置 找到运行设置&#xff0c;将微信开发者工具放入到Hbuilder中&#xff0c; 打开后出现 如下 bug 解…...

tauri项目,如何在rust端读取电脑环境变量

如果想在前端通过调用来获取环境变量的值&#xff0c;可以通过标准的依赖&#xff1a; std::env::var(name).ok() 想在前端通过调用来获取&#xff0c;可以写一个command函数&#xff1a; #[tauri::command] pub fn get_env_var(name: String) -> Result<String, Stri…...