跟着我学Python进阶篇:04. 错误和异常

往期文章

跟着我学Python基础篇:01.初露端倪
跟着我学Python基础篇:02.数字与字符串编程
跟着我学Python基础篇:03.选择结构
跟着我学Python基础篇:04.循环
跟着我学Python基础篇:05.函数
跟着我学Python基础篇:06.列表
跟着我学Python基础篇:07.文本
跟着我学Python基础篇:08.集合和字典


跟着我学Python进阶篇:01.试用Python完成一些简单问题
跟着我学Python进阶篇:02.面向对象(上)
跟着我学Python进阶篇:03.面向对象(下)


目录

  • 往期文章
  • 1. 错误和异常的简介
    • 1.1 异常
    • 1.2 Python常见异常
  • 2. 捕获异常
    • 2.1 try-expect语句
    • 2.2 获取异常提示信息
    • 2.3 捕获多个异常
    • 2.4 捕获所有异常
    • 2.5 else语句
    • 2.6 finally语句
  • 3. 抛出异常
    • 3.1 raise语句
    • 3.2 异常的传递
    • 3.3 assert断言语句
  • 4. 自定义异常
  • 5. with语句处理异常
    • 5.1 with语句
    • 5.2 上下文管理器
    • 5.3 自定义上下文管理器

1. 错误和异常的简介

程序中的错误分为逻辑错误和语法错误,语法错误是指软件的编写不符合Python语言的语法规定,导致无法被解释器解释或者编译器编译。这些错误必须修正,程序才能运行。语法错误的类型是SyntaxError。程序运行以后出现的错误是逻辑错误,逻辑错误可能是由于外界条件允许的,也可能是程序本身设计不严谨导致的。不管哪种错误,只要被Python检测到,都会发生异常。

1.1 异常

在程序运行期间检测到的错误称之为异常,如果异常不被处理,默认的方式是程序崩溃,并给出错误提示。

1.2 Python常见异常

AttributeError:尝试访问未定义的属性或方法时引发的异常。
FileNotFoundError:尝试打开不存在的文件时引发的异常。
IndexError:尝试访问列表、元组或字符串中不存在的索引时引发的异常。
KeyError:尝试访问字典中不存在的键时引发的异常。
NameError:尝试访问未声明或未初始化的变量时引发的异常。
TypeError:操作或函数应用于不适当类型的对象时引发的异常。
ValueError:传递给函数的参数具有正确的类型,但具有不合适的值时引发的异常。
ZeroDivisionError:除以零时引发的异常。

2. 捕获异常

Python中使用try-expect语句处理异常,其中try语句检测异常,except语句捕获异常。

2.1 try-expect语句

在这里插入图片描述

首先,“try” 块中的代码会被执行。这是可能引发异常的代码块。
如果在 “try” 块中的代码执行期间没有发生任何异常,那么 “except” 块将被跳过,程序将继续执行后续的代码。
如果在 “try” 块中的代码执行期间引发了一个异常,那么与该异常类型匹配的第一个 “except” 块将被执行。如果有多个 “except” 块,并且匹配多个异常类型,只有第一个匹配的块将被执行,其他的块将被忽略。
异常被捕获后,与异常相关的 “except” 块中的代码将被执行。这是你可以在其中处理和恢复异常的地方。
如果没有与异常类型匹配的 “except” 块,或者异常类型没有被指定,那么该异常将传递给上一层的调用堆栈,直到找到能够处理该异常的 “except” 块或者程序终止。

2.2 获取异常提示信息

有些异常可以在程序中纠正,有些不能。一般程序中会维护一个日志,记录程序中出现的所有异常,此时可以使用as获取系统反馈的具体信息。

例如:

try:
    print("我的年龄是"+18)
    print("我叫富豪")
except TypeError as error:
    print("错误信息:")
    print(error)

在这里插入图片描述

2.3 捕获多个异常

一个代码可能出现多个异常,可以将多个特定异常组成一个元祖放在一个except语句后处理,也可以多个except字句联合使用。

try:
    print(abc)
    print(2/0)
except(NameError,ZeroDivisionError) as error:
    print(error)

在这里插入图片描述
同时捕获多个异常,只能使用一种方式进行处理,如果希望对不同的异常采用不同的处理方式,可以使用多个except字句,可以使用下面的写法:

try:
    print(2/0)
    print(abc)
except NameError as error:
    print(error)
except ZeroDivisionError:
    print("不能使用0作为除数")

注:Python2中把多个异常用逗号隔开,Python3需要将多个异常元祖组织起来,也就是多个圆括号。

2.4 捕获所有异常

在Python中捕获所有异常有两种方式,一种使用Exception,由于Exception是所有异常的基类,所以可以包含所有异常。

try:
    demo_list=[1,2,3,4]
    print(demo_list[5])
except Exception as error:
    print(error)
    print("错误")
    

在这里插入图片描述
另一种方式是使用except,如:

try:
    demo_list=[1,2,3,4]
    print(demo_list[5])
except:
    print("错误")

在这里插入图片描述
在except后缺异常类型,也会将所有异常都捕获。不过这种方式并不推荐,一是不能获取错误的具体信息,二是它还会捕获我们并不想捕获的异常,比如用户终止执行的Ctrl C操作,以及用sys.exit()函数程序终止操作。

异常处理的主要目的是防止因外部环境变化导致程序无法控制的错误,而不应该用于处理程序设计错误,将所有代码用try语句包含是不正确的。
捕获异常之后要进行相应的处理,如果异常之后用pass直接忽略掉,会隐藏掉程序出错的原因,不利于程序的运行和维护,也是不推荐的。

2.5 else语句

else语句可以和try-expect配合使用:
try:
可能会引发异常的代码块

except ExceptionType1:
处理 ExceptionType1 类型的异常的代码块

except ExceptionType2:
处理 ExceptionType2 类型的异常的代码块

else:
没有发生异常时执行的代码块

2.6 finally语句

finally语句与try语句联合使用,表示无论try语句是否出错都会执行语句。
try:
# 可能会引发异常的代码块
# …
finally:
# 无论是否发生异常,都会执行的代码块
# …

3. 抛出异常

如果捕获到的异常在本级无法处理,或者不应由本级处理,也可以将异常抛出,交给上一级代码处理。

3.1 raise语句

raise语句用于抛出特定的异常。

  1. 创建类的实例对象,引发异常:
    raise 异常类名
  2. 引发异常实例对象对应的异常
    raise 异常类实例对象
  3. 重新引发刚才发生的异常
    raise

在上述格式中,第一种和第二种是对等的,都会引发指定异常类的实例,但是第一种形式隐式地创建了异常类的实例,而第二种形式是最常见的,直接提供一个实例,第三种用于重新引发刚刚发生的异常。

下面通过实例来对raise语句进行介绍:

  1. 使用类名引发异常

当raise语句指定异常类名时,会创建该类的实例对象,然后引发异常。

raise IndexError

在这里插入图片描述

  1. 使用异常类的实例引发异常
    通过显式地创建异常类的实例,直接使用该实例对象来引发异常。
index=IndexError()
raise index

在这里插入图片描述

  1. 传递异常
    不带任何参数的raise语句,可以再次引发刚刚发生过的异常,作用就是向外传递异常。
try:
    raise IndexError
except:
    print("出错了")
    raise

在这里插入图片描述

  1. 指定异常的描述信息
    当使用raise语句抛出异常时,还能给异常类指定描述信息。
raise IndexError("索引超出下标范围")

在这里插入图片描述

  1. 异常引发异常
    如果要在异常中抛出另一个异常,可以使用raise from语句实现。

在这里插入图片描述

3.2 异常的传递

如果异常没有被处理,默认情况将会上传给上层代码,逐级向上传递,如果最上层的代码没有处理,则会使用系统默认方式。

3.3 assert断言语句

assert语句是一种用于调试和测试的Python语句。它用于检查一个条件是否为真,如果为假,则会引发一个AssertionError异常。

assert语句的语法如下:
assert condition, message

4. 自定义异常

自定义异常类需要创建一个类,让他继承自Exception类或其子类即可。

class MyCustomException(Exception):
    def __init__(self, message):
        super().__init__(message)
        self.error_code = 100

    def log_error(self):
        # 自定义异常类的方法
        print("Logging error: ", self.__str__())

try:
    raise MyCustomException("Something went wrong!")
except MyCustomException as e:
    print("Exception occurred:", e)
    e.log_error()

5. with语句处理异常

with语句支持创建资源、抛出异常、释放资源等操作。

5.1 with语句

with语句适用于对资源进行访问的场合,无论资源使用过程中是否发生异常,都会执行必要的释放资源的操作。比如文件使用后自动关闭,线程中锁的自动获取和释放。
with语句的语法格式如下:
with 上下文表达式 [as 资源对象]:
对对象的操作

上下文表达式返回一个上下文管理对象,如果指定as子句,该对象并不赋值给as子句中的资源对象,而是将上下文管理器的_enter()_方法赋值给资源对象,资源对象可以是单个变量也可以是元祖。

例如,对with语句操作文件对象的示例如下:

with open(‘test.txt’) as file:
for aline in file:
print(aline)

with语句从Python2.5 开始引入(需通过from_future_import with_statement导入),从Python2.6开始可以缺省。

不是所有对象都可以使用with语句,只有支持上下文管理协议的对象才可以。

5.2 上下文管理器

上下文管理协议与with有关的概念包括:

  1. 上下文管理协议(Context Management Protocal)
    enter(): 当进入with语句块时,会调用该方法。它负责返回一个值,通常是对象本身或与上下文相关的资源。
    exit(exc_type, exc_value, traceback): 当离开with语句块时,无论是正常离开还是发生异常,都会调用该方法。它负责处理上下文退出时的清理工作,关闭资源等。

  2. 上下文管理器
    支持上下文管理协议的对象就是上下文管理器,这种对象实现了_enter_()和_exit_()方法,使用with语句即可调用上下文管理器,它负责建立运行时上下文。

  3. 运行时上下文
    由上下文管理器创建,通过上下文管理器的_enter_()和_exit_()方法实现。

  4. 上下文表达式
    with语句在with关键字后出现的表达式,该表达式要返回一个支持上下文管理协议的对象,也就是返回一个上下文管理器。

  5. 语句体
    由with语句包括起来的包括块,表示对资源对象的操作。在执行语句之前会执行上下文管理器的_enter_()方法,执行之后调用_exit_()方法。

了解了上下文管理器就理解了with语句执行过程了:

当执行到with语句时,首先调用上下文管理器对象的_enter_()方法,该方法负责获取资源并返回一个值。
进入with语句块,执行其中的代码。
如果在with语句块中发生异常,异常会被捕获。
无论是否发生异常,都会调用上下文管理器对象的_exit_(exc_type, exc_value, traceback)方法。如果没有发生异常,这三个参数都是None;如果有异常,这三个参数分别表示异常类型、异常实例和追溯信息。

5.3 自定义上下文管理器

要自定义上下文管理器,需要创建一个类并实现上下文管理协议的方法_enter_()和_exit_()。

class MyContext:
    def __enter__(self):
        print("Entering context")
        # 返回要在上下文中使用的对象或资源
        return "Hello, world!"

    def __exit__(self, exc_type, exc_value, traceback):
        print("Exiting context")
        # 处理上下文退出时的清理工作
        if exc_type:
            print("Exception occurred:", exc_type, exc_value)

# 使用自定义的上下文管理器
with MyContext() as context:
    print(context)
    # 在上下文中执行一些操作

# 上下文外部继续执行其他代码
print("Outside context")

在上面的例子中,我们定义了一个名为MyContext的上下文管理器类。它实现了__enter_()和 exit()方法。

在_enter__()方法中,我们可以执行一些准备工作,并返回一个对象或资源,该对象或资源将在with语句块中使用。在这个示例中,我们返回了一个简单的字符串。

在_exit_()方法中,我们可以处理上下文退出时的清理工作,例如关闭文件、释放资源等。如果在with语句块中发生异常,异常信息会传递给_exit__()方法的参数。

然后,我们使用with语句创建了一个MyContext对象,并将其赋值给context变量。在`with语句块中,我们打印了context的值,并执行了一些操作。

当离开with语句块时,无论正常离开还是发生异常,都会自动调用_exit_()方法,进行清理工作。在这个示例中,我们打印了退出上下文的信息。

最后,在上下文外部继续执行其他代码,打印了"Outside context"。

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

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

相关文章

03 SpringBoot实战 -微头条之首页门户模块(跳转某页面自动展示所有信息+根据hid查询文章全文并用乐观锁修改阅读量)

1.1 自动展示所有信息 需求描述: 进入新闻首页portal/findAllType, 自动返回所有栏目名称和id 接口描述 url地址:portal/findAllTypes 请求方式:get 请求参数:无 响应数据: 成功 {"code":"200","mes…

SPE单对以太网线束测试

根据IEC63171-1,严格执行此标准,进行测试: 两端压接的LC端子,有人会有疑问为什么以上测试参数的DC LOOP电阻,那么高,今天就此来探讨一下: 1,没有2m的线做基准测试; 2&a…

Win11在某些时候想要关闭windows安全中心应该怎么做,安装navicat事例

比如在安装navicat时,需要注册,注册机被删,就是windows安全中心干的,所以要想办法,不让他把注册机删掉,那么这里有一个比较巧妙的办法,就使用排除项,关闭 实时保护, 添…

机器学习核心算法

目录 逻辑回归 算法原理 决策树 决策树算法概述 树的组成 决策树的训练与测试 切分特征 衡量标准--熵 信息增益 决策树构造实例 连续值问题解决 预剪枝方法 分类与回归问题解决 决策树解决分类问题步骤 决策树解决回归问题步骤 决策树代码实例 集成算法 Baggi…

泡泡玛特旗下IP亮相2024米兰时装周 LABUBU等化身时尚观察员​

2024年1月14日,在意大利米兰时装周上,泡泡玛特旗下IP THE MONSTERS成员LABUBU、ZIMOMO惊艳亮相PRONOUNCE珀琅汐2024秋冬大秀现场,作为时尚观察员的LABUBU和ZIMOMO以其独特的潮玩形象打动了顶级时尚圈。 据了解,泡泡玛特和PRONOUNC…

纯前端实现上一条下一条切换,并实现跨页切换上一条下一条

1.开发遇到了新的需求:再进入到视频播放界面,需要支持可以点击上一条下一条按钮,实现数据切换的功能 2.功能开发的理解 需要考虑到以上的需求, 1.由于视频的入口不一致,要根据入口的不同,实现不同的上一条…

手动加好友太麻烦,想要自动加好友?

问:手上有一批客户数据,但每天手动添加很费时,而且还是多个微信号同时加好友,很容易出现数据重复加怕出错。有没有什么方法可以自动加好友呀,能支持多个号一起设置自动加好友,还可以设置定时启动任务操作的…

Linux docker 容器安装superset全部过程(superset docker版本)

解释一波 Apache Superset是一款由Python语言为主开发的开源时髦数据探索分析以及可视化的报表平台;她支持丰富的数据源,且拥有多姿多彩的可视化图表选择。 官网 :https://superset.apache.org/github :https://github.com/apache…

夜莺监控发布 v6.7 版本,推送部分商业版功能

熟悉夜莺的小伙伴都知道夜莺分为开源版、专业版、企业版,三个版本良性发展。近期夜莺团队发布了 v6.7 版本,把机器Metadata管理功能推送到了开源版,下面是该功能的简单介绍。 如上图,机器列表页面的机器标识部分,加了超…

RAG和AGI以及AIGC,你知道多少?

RAG(Retrieval-Augmented Generation): RAG是一种模型架构,结合了检索(retrieval)和生成(generation)的方法。它使用检索模块从大规模的知识库中检索相关信息,然后使用生…

Linux:gcc的相关知识

目录 gcc的翻译(编译)过程: 预处理: 条件编译: 编译: 汇编&链接: 什么是链接? 安装静态库: 静态库的使用: 动态静态的对比: 优缺对比…

类和对象(友元、运算符重载、继承、多态)---C++

类和对象 4.友元4.1全局函数做友元4.2类做友元4.3成员函数做友元 5.运算符重载5.1 加号运算符重载5.1.1成员函数实现运算符重载5.1.2全局函数实现运算符重载 5.2 左移运算符重载5.2.1全局函数实现运算符重载5.2.2成员函数实现运算符重载 5.3 递增/递减运算符重载5.3.1 前置5.3.…

软件产品为什么要测试才能上线?测试可以发现所有bug吗?

在现如今信息时代,软件产品已经成为人们生活中不可或缺的一部分。无论是在工作中还是在娱乐休闲时,我们都需要依赖各种软件来完成各种任务。然而,你是否注意到了身边的软件产品都是经过严格的测试才能上线的呢?那么为什么软件产品必须要经过…

操作系统【OS】Ch2 进程同步与互斥机制

进程同步与互斥机制1:硬件和软件方法 硬件方法 也称为低级方法、元方法 不能实现让权等待 中断屏蔽 使用开/关中断指令实现简单高效只适用于单处理机只适用于操作系统内核进程【因为关中断的权力不能交给用户】 TestAndSet 实现简单适用于多处理机不满足让权等待…

【GAMES101】Lecture 09 重心坐标

我们之前说着色过程中以及这个计算法线的时候需要用到这个插值(Interpolation),然后插值是通过这个重心坐标(Barycentric Coordinates)来实现的 目录 重心坐标 插值 重心坐标 注意哈我们这里说的三角形的重心坐标并…

RT-DETR优化改进:IoU系列篇 | Focaler-IoU​​​​​​​更加聚焦的IoU损失Focaler-IoU |2024年最新发表

🚀🚀🚀本文改进:Focaler-IoU更加聚焦的IoU损失Focaler-IoU,能够在不同的检测任务中聚焦不同的回归样本,使用线性区间映射的方法来重构IoU损失 🚀🚀🚀RT-DETR改进创新专栏:http://t.csdnimg.cn/vuQTz 🚀🚀🚀学姐带你学习YOLOv8,从入门到创新,轻轻松松搞…

(2024,强化学习,扩散,奖励函数)扩散模型的大规模强化学习

Large-scale Reinforcement Learning for Diffusion Models 公和众和号:EDPJ(进 Q 交流群:922230617 或加 VX:CV_EDPJ 进 V 交流群) 目录 0. 摘要 3. 方法 3.1. 使用多步骤 MDP 的策略梯度 3.2. 基于分布的奖励函…

正则表达式初版

一、简介 REGEXP: Regular Expressions,由一类特殊字符及文本字符所编写的模式,其中有些字符(元字符)不表示字符字面意义,而表示控制或通配的功能,类似于增强版的通配符功能,但与通…

Docker部署

Docker简介 Docker是一个开源的容器引擎,它有助于更快地交付应用。 Docker可将应用程序和基础设施层隔离,并且能将基础设施当作程序一样进行管理。使用 Docker可更快地打包、测试以及部署应用程序,并可以缩短从编写到部署运行代码的周期。 &a…

数据结构奇妙旅程之二叉树题型解法总结

꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱ ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客 本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN …