Python中的错误处理 - 使用try、except、else和finally进行解释,并附带代码示例

最近,我的经理委派我创建一个自动报告。我设计的报告非常简单。它包括一些来自数据库的数字和一些基本的数学运算。我很兴奋最终可以向公司展示我的惊人的Python技能。

我完成并交付了产品。一切都很顺利。至少,直到大约两周后。我的报告由于除以零错误而随机失败了。来了个笑声轨道。

我的短篇故事缺少细节,但应该强调在编写程序时处理边界情况和错误的重要性。这份报告本应是展示我的Python技能的机会。然而,它却变成了一个有点尴尬的时刻。

所以,让我们花点时间学习使用Python标准库进行基本的错误处理。我将重点介绍一些你需要开始的东西。

在开始处理异常之前,你应该对Python基础知识有很好的掌握。你需要知道为什么会抛出异常才能处理它们!

(本文视频讲解:java567.com)

我们将介绍以下内容:

  1. Python中的Try和Except语句
  2. 使用Else子句进行条件执行
  3. 内置异常
  4. 自定义异常
  5. 性能考虑

Python中的Try和Except语句

tryexcept语句是处理异常的主要方法。它们的形式如下:

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("出错了")
    
# 出错了

让我们来分析上面的代码,以确保我们理解一致:

  1. 第1行将值0赋给变量x
  2. 第2行和第3行打开一个try子句,并尝试将5除以变量x
  3. 第4行和第5行打开一个except子句,用于任何ZeroDivisionError,并指示程序在尝试将任何东西除以0时打印一条消息

你可能已经注意到了问题。我的变量x的值是0,我试图将5除以x。世界上最好的数学家也不能除以0,Python也不能。那么会发生什么呢?

如果我们不处理错误,程序在尝试将5除以x时会立即终止。由于程序没有明确的指示如何处理异常,所以我们在第4行创建了except子句,并提供了程序在尝试将某些东西除以0时要采取的步骤。

这就是处理异常的整个思想:当程序遇到无法简单忽略的错误时,你需要告诉程序该怎么做。让我们看看tryexcept子句是如何工作的。

解析Try语句

TryExcept语句遵循一种模式,允许你可靠地处理代码中的问题。我们来看看这个模式。

首先,try子句中的代码尝试执行。

接下来,我们有三种可能性:

Try子句中没有错误

如果try子句中的代码没有任何错误,程序将:

  1. 执行try子句
  2. 跳过所有except子句
  3. 继续正常运行
x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("出错了")

print("我在try子句之后执行!")

# 5.0
# 我在try子句之后执行!

你可以看到,在这个修改后的示例中,try子句(第3行和第4行)没有问题。代码将执行,except子句将被跳过,并且程序将在tryexcept语句结束后继续执行。

Try子句中有错误并且指定了异常

如果try子句中的代码确实引发异常并且在任何except关键字后指定了异常类型,程序将:

  1. 跳过try子句中剩余的代码
  2. 执行匹配的except子句中的任何代码
  3. 继续正常运行
x = 0
try:
    print(5 / x)
except:
    print("出错了")
    
print("我在try子句之后执行!")

# 出错了
# 我在try子句之后执行!

回到我的第一个例子,我将我们的变量x改回了值0,并尝试将5除以x。这会产生一个ZeroDivisionError。由于我的except语句指定了这种类型的异常,所以该子句中的代码在程序继续正常运行之前执行。

Try子句中有错误但未指定异常

最后,如果程序在try子句中引发了异常,但在任何except语句中未指定异常,那么程序将:

  1. 停止执行程序并抛出错误
x = 0
try:
    print(5 / y)
except:
    print("出错了")

print("我在try子句之后执行!")

# NameError: name 'y' is not defined

在上面的示例中,我试图将5除以变量y,但该变量不存在。这会引发一个NameError。我没有告诉程序如何处理NameError,所以唯一的选择就是终止程序。

清理工作

Tryexcept是处理错误的主要工具,但你可以使用的一个可选子句是finallyfinally子句将始终执行,无论是否发生错误。

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 我是except子句!
# 我是finally子句!
# 我在try子句之后执行!

在这个例子中,我创建了我们喜欢的ZeroDivisionError。你可以看到执行顺序是:

  1. except子句
  2. finally子句
  3. 之后的任何代码

一旦我们修复try子句不再引发错误,你仍然会看到类似的执行顺序。except子句不再运行,try子句将执行。

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 5.0
# 我是finally子句!
# 我在try子句之后执行!

你会注意到唯一的区别是try子句成功执行,因为没有抛出异常。finally子句和之后的代码会像你预期的那样执行。

这对于一些情况很有用,当你想要无论tryexcept子句的结果如何都要进行清理时。关闭连接、关闭文件和记录日志等操作都是finally子句的很好候选对象。

使用Else子句进行条件执行

另一个可选子句是else子句。else子句很简单:如果try子句中的代码执行时没有抛出错误,那么else子句中的代码也将执行。

x = 1
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
else:
    print("我是else子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 5.0
# 我是else子句!
# 我是finally子句!
# 我在try子句之后执行!

这个例子的执行顺序是:

  1. try子句
  2. else子句
  3. finally子句
  4. 之后的任何代码

如果在try子句中出现异常或错误,else子句将被忽略。

x = 0
try:
    print(5 / x)
except ZeroDivisionError:
    print("我是except子句!")
else:
    print("我是else子句!")
finally:
    print("我是finally子句!")

print("我在try子句之后执行!")

# 我是except子句!
# 我是finally子句!
# 我在try子句之后执行!

内置异常

到目前为止,你已经看到我写了两种不同的命名异常:NameErrorZeroDivisionError。如果我需要其他异常呢?

Python标准库中有一整套异常列表。这些异常几乎可以满足你处理任何错误或异常的需求。

以下是一些可能很重要的异常:

  • KeyError – 在字典中找不到键
  • IndexError – 在可迭代对象上索引超出范围
  • TypeError – 将函数或操作用于错误类型的对象
  • OSError – 一般的操作系统错误

还有很多其他的异常,可以在Python文档中找到。我鼓励你去看看。你不仅会更擅长处理错误,还会探索你的Python程序可能真正出错的地方。

自定义异常

如果你需要扩展功能,还可以定义自定义异常。

class FooError(Exception):
    def __init__(self, message):
        self.message = message
    
    def foo(self):
        print("bar")

在上面的示例中,我创建了一个新类,并将其扩展自异常类。现在,我可以编写自定义功能,并像对待其他对象一样处理此异常。

try:
    raise FooError("这是一个测试错误")
except FooError as e:
    e.foo()

# bar

这里,我故意引发了我的新FooError。我捕获了FooError,并给它起了别名e。现在,我可以访问我在创建的类中内置的foo()方法。

这为处理错误提供了一系列可能性。自定义日志记录、更深入的跟踪或任何你需要的其他功能都可以编码和创建。

性能考虑

现在你已经了解了tryexcept和异常对象的基础知识,你可以开始考虑在你的代码中使用它们来优雅地处理错误。但是,代码性能会受到多大影响呢?

简短的答案是没有。随着Python 3.11的发布,当没有抛出异常时,使用tryexcept语句几乎不会减慢速度。

捕获错误确实会导致一些减速。但总的来说,捕获这些错误总比整个程序崩溃好。

在Python的早期版本中,使用tryexcept子句确实会导致一些额外的执行时间。如果你不是最新的,请记住这一点。

总结

感谢你阅读到这里。你的未来自己和客户会为你的错误处理感谢你。

我们讨论了tryexceptelsefinally子句及其执行顺序,以及在什么情况下它们被执行。我们还复习了创建自定义异常的基础知识。

最重要的是要记住,tryexcept子句是捕获错误的主要方式,你应该在有风险、容易出错的代码中使用它们。

此外,请记住,捕获错误将使你的代码更加弹性,并让你看起来更像一个优秀的程序员。

(本文视频讲解:java567.com)

Error Handling in Python – try, except, else, & finally Explained with Code Examples

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

编程新手必看,python中条件控制语句学习(13)

介绍: Python3中的条件控制主要通过if、elif和else关键字来实现,它们用于根据条件执行特定的代码块。 if语句:这是最基本的条件控制结构。如果满足某个条件(条件为True),则执行相应的代码块。在Python中&am…

蓝牙app设计(方案二) E4A (时钟 优缺点)

例程改的! 主界面 虽然上面有搜索功能,但是本人建议先自行配对在使用,这样更好用,把要使用的设备收藏一下更好找哦(这样就是橙色的了,只需要点对应蓝牙左边) 代码修改部分 原版是不停向下滚动显示,这样个人觉得不太好看,所以加了个时钟,到对应时钟周期清空(达到刷…

Java-Web过滤器

文章目录 1.基本介绍1.为什么需要过滤器?2.基本介绍3.过滤器的基本原理 2.快速入门1.文件目录2.环境配置创建maven项目,导入依赖 3.代码实现1.login.jsp2.LoginCheck.java3.ManagerFilter.java编写过滤规则4.配置web.xml告诉tomcat5.admin.jsp 3.Filter的…

【nodejs基础学习三-浏览器偏好设置】

系列文章目录 第一章 nodejs基础学习–注释、变量、运算符、字符串、函数(一) 第二章 nodejs基础学习–循环、对象字符、模块导入出(二) 第三章 nodejs基础学习三-浏览器设置 系列文章目录一、开发者模式二、web偏好设置 一、开发…

【病毒分析】DevicData勒索病毒分析

1.背景 1.1来源 近期,Solar团队收到某医疗单位的援助请求,该公司的计算机受到了某勒索病毒的侵害,所有的文件被加密并且添加了.DevicData-P-470b1abd后缀,我司人员现场取证进行排查并提取加密器,本文是对于加密器的分析。 2.恶…

MySQL高级详解

文章目录 约束概述分类主键约束概述特点定义及删除主键自增 唯一约束作用语法 非空约束作用语法 面试题:非空唯一约束与主键约束有什么区别默认值约束作用语法 总结 表关系及外键约束表关系概述分类一对多关系表设计外键字段设计原则 多对多关系表设定设计原则 一对…

Linux下网络编程基础知识--协议

网络基础 这一个课程的笔记 相关文章 协议 Socket编程 高并发服务器实现 线程池 协议 一组规则, 数据传输和数据的解释的规则。 比如说依次发送文件的文件名, 文件的大小, 以及实际的文件, 这样规定发送一个文件的顺序以及发送的每一个部分的格式等可以算是一种协议 型协议 …

探索ChatGPT-Plus:AI 助手全套开源解决方案

探索ChatGPT-Plus:AI 助手全套开源解决方案 ChatGPT-plus是一种新型的对话生成模型,它是在OpenAI的ChatGPT基础上进行了改进和优化的版本。ChatGPT-plus的出现引起了广泛关注,因为它在对话生成方面展现出了更加出色的表现和能力。在本文中&am…

【C++第三阶段】stackqueue容器

以下内容仅为当前认识,可能有不足之处,欢迎讨论! 文章目录 stack容器queue容器 stack容器 是什么?功能是什么?常用接口是什么?局限性有哪些?优势又有哪些? 栈容器,先进…

智能驾驶“血拼”端到端,元戎启行准备好了吗?

智能驾驶从规则驱动转向数据驱动,正在引导行业进入新的竞争区间。 在之前的中国电动汽车百人会论坛(2024) 上,比亚迪董事长兼总裁王传福认为,新能源汽车渗透率在未来3个月将超过50%。自动驾驶公司元戎启行CEO周光指出,在上半场的…

Python实现BOA蝴蝶优化算法优化BP神经网络回归模型(BP神经网络回归算法)项目实战

说明:这是一个机器学习实战项目(附带数据代码文档视频讲解),如需数据代码文档视频讲解可以直接到文章最后获取。 1.项目背景 蝴蝶优化算法(butterfly optimization algorithm, BOA)是Arora 等人于2019年提出的一种元启发式智能算…

社交网络的未来图景:探索Facebook的发展趋势

随着科技的不断进步和社会的快速变迁,社交网络作为连接人与人之间的重要纽带,扮演着日益重要的角色。而在众多社交网络中,Facebook作为老牌巨头,一直在探索着新的发展路径,引领着社交网络的未来图景。本文将深入探索Fa…

跟着Carl大佬学leetcode之27 移除元素

来点强调,刷题是按照代码随想录的顺序进行的,链接如下https://www.programmercarl.com/本系列是记录一些刷题心得和学习过程,就看到题目自己先上手试试,然后看程序员Carl大佬的解释,自己再敲一遍修修补补,练…

数组与伪数组的区别

大家都知道,在js中使用 document.querySelectorAll(选择器)获取到的为该选择器能选择到的所有元素组成的伪数组,所谓伪数组,就是外表和数组一样,能够使用索引遍历,但本质是对象。 数组与伪数组之间的区别&…

C语言面试题之合法二叉搜索树

合法二叉搜索树 实例要求 实现一个函数,检查一棵二叉树是否为二叉搜索树; 示例 1: 输入:2/ \1 3 输出: true 示例 2: 输入:5/ \1 4/ \3 6 输出: false 解释: 输入为: [5,1,4,null,null,3,6]。根节点的值为 5 ,但是其右子节点值为 4 …

测试开发是“懂测试的开发”还是“懂开发的测试”?

这是个很有意思的话题,我一开始画了这么一张图: 就我自身的工作而言,用着开发的技术,做着开发差不多的工作。归为开发一类并无不妥! 后来,我细细琢磨了一下,改为了下图。 其实答案也非常明显&a…

动态调整学习率方法(仅供自己学习)

目录 一、StepLR 二、MultiStepLR 三、ExponentialLR 四、CosineAnnealingLR 五、ReduceLRonPlateau 六、LambdaLR 小结:学习率调整​​​​​​​ 一、StepLR optimizer torch.optim.SGD(model.parameters(), lrlearn_rate) scheduler torch.optim.lr_sch…

Linux目录结构知识

一、认识Linux目录 1) Linux目录结构知识 1) win: 目录顶点是盘符 C/D/E 。所有的目录结构都在不同的盘符下面,不同的盘之间不能沟通的。 2) Linux: 目录顶点是 / ,称为根。所有的目录结构都在根下面,他的目录之间都…

Day37:LeedCode 738.单调递增的数字 968.监控二叉树 蓝桥杯 翻转

738. 单调递增的数字 当且仅当每个相邻位数上的数字 x 和 y 满足 x < y 时&#xff0c;我们称这个整数是单调递增的。 给定一个整数 n &#xff0c;返回 小于或等于 n 的最大数字&#xff0c;且数字呈 单调递增 。 示例 1: 输入: n 10 输出: 9 思路: 假设这个数是98,…

MuJoCo 入门教程(八)Model仓库

系列文章目录 前言 一、MuJoCo 动物园 一个物理仿真器的好坏取决于它所仿真的模型&#xff0c;而在像 MuJoCo 这样功能强大、建模选项众多的仿真器中&#xff0c;很容易创建出行为与预期不符的 "坏 "模型。MuJoCo Menagerie 的目标是为社区提供一个设计精良、开箱即用…