Python超级详细的raise用法

news2024/9/9 5:29:34

当程序出现错误时,系统会自动引发异常。除此之外,Python 也允许程序自行引发异常,自行引发异常使用 raise 语句来完成。

很多时候,系统是否要引发异常,可能需要根据应用的业务需求来决定,如果程序中的数据、执行与既定的业务需求不符,这就是一种异常。由于与业务需求不符而产生的异常,必须由程序员来决定引发,系统无法引发这种异常。

如果需要在程序中自行引发异常,则应使用 raise 语句。raise 语句有如下三种常用的用法:

raise:单独一个 raise。该语句引发当前上下文中捕获的异常(比如在 except 块中),或默认引发 RuntimeError 异常。

raise 异常类:raise 后带一个异常类。该语句引发指定异常类的默认实例。

raise 异常对象:引发指定的异常对象。

上面三种用法最终都是要引发一个异常实例(即使指定的是异常类,实际上也是引发该类的默认实例),raise 语句每次只能引发一个异常实例。

可以利用 raise 语句再次改写前面五子棋游戏中处理用户输入的代码:

try :
    #将用户输入的字符串以逗号( ,)作为分隔符,分隔成两个字符串
    x_str, y_str = inputStr.split(sep =",")
    #如果要下棋的点不为空
    if board[int(y_str) - 1] [int(x_str) - 1] != "+":
    #引发默认的RuntimeError异常
    raise
    #把对应的列表元素赋为”●”
    board [int(y_str) - 1] [int(x_str) - 1] = ”●”
except Exception as e:
    print (type(e))
    inputStr = input("您输入的坐标不合法,请重新输入,下棋坐标应以x,y 的格式\n")
    continue

上面程序中第 7 行代码使用 raise 语句来自行引发异常,程序认为当用户试图向一个已有棋子的坐标点下棋时就是异常。当 Python 解释器接收到开发者自行引发的异常时,同样会中止当前的执行流,跳到该异常对应的 except 块,由该 except 块来处理该异常。也就是说,不管是系统自动引发的异常,还是程序员于动引发的异常,Python 解释器对异常的处理没有任何差别。

即使是用户自行引发的异常,也可以使用 try except 来捕获它。当然也可以不管它,让该异常向上(先调用者)传播,如果该异常传到 Python 解释器,那么程序就会中止。

下面示例示范了处理用户引发异常的两种方式:

def main():
    try:
        # 使用try...except来捕捉异常
        # 此时即使程序出现异常,也不会传播给main函数
        mtd(3)
    except Exception as e:
        print('程序出现异常:', e)
    # 不使用try...except捕捉异常,异常会传播出来导致程序中止
    mtd(3)
def mtd(a):
    if a > 0:
        raise ValueError("a的值大于0,不符合要求")
main()

从上面程序可以看到,程序既可在调用 mtd(3) 时使用 try except 来捕获异常,这样该异常将会被 except 块捕获,不会传播给调用它的函数;也可直接调用 mtd(3),这样该函数的异常就会直接传播给它的调用函数,如果该函数也不处理该异常,就会导致程序中止。

运行上面程序,可以看到如下输出结果:

程序出现异常: a的值大于0,不符合要求
Traceback (most recent call last):
  File "C:\Users\mengma\Desktop\1.py", line 13, in <module>
    main()
  File "C:\Users\mengma\Desktop\1.py", line 9, in main
    mtd(3)
  File "C:\Users\mengma\Desktop\1.py", line 12, in mtd
    raise ValueError("a的值大于0,不符合要求")
ValueError: a的值大于0,不符合要求

上面第一行输出是第一次调用 mtd (3) 的结果,该方法引发的异常被 except 块捕获并处理。后面的大段输出则是第二次调用 mtd(3) 的结果,由于该异常没有被 except 块捕获,因此该异常一直向上传播,直到传给 Python 解释器导致程序中止。

第二次调用 mtd(3) 引发的以“File”开头的三行输出,其实显示的就是异常的传播轨迹信息。也就是说,如果程序不对异常进行处理,Python 默认会在控制台输出异常的传播轨迹信息。

自定义异常类

很多时候,程序可选择引发自定义异常,因为异常的类名通常也包含了该异常的有用信息。所以在引发异常时,应该选择合适的异常类,从而可以明确地描述该异常情况。在这种情形下,应用程序常常需要引发自定义异常。

用户自定义异常都应该继承 Exception 基类或 Exception 的子类,在自定义异常类时基本不需要书写更多的代码,只要指定自定义异常类的父类即可。

下面程序创建了一个自定义异常类(程序一):

class AuctionException(Exception): pass

上面程序创建了 AuctionException 异常类,该异常类不需要类体定义,因此使用 pass 语句作为占位符即可。

在大部分情况下,创建自定义异常类都可采用与程序一相似的代码来完成,只需改变 AuctionException 异常的类名即可,让该异常的类名可以准确地描述该异常。

except 和 raise 同时使用

在实际应用中对异常可能需要更复杂的处理方式。当一个异常出现时,单靠某个方法无法完全处理该异常,必须由几个方法协作才可完全处理该异常。也就是说,在异常出现的当前方法中,程序只对异常进行部分处理,还有些处理需要在该方法的调用者中才能完成,所以应该再次引发异常,让该方法的调用者也能捕获到异常。

为了实现这种通过多个方法协作处理同一个异常的情形,可以在 except 块中结合 raise 语句来完成。如下程序示范了except 和 raise 同时使用的方法:

class AuctionException(Exception): pass
class AuctionTest:
    def __init__(self, init_price):
        self.init_price = init_price
    def bid(self, bid_price):
        d = 0.0
        try:
            d = float(bid_price)
        except Exception as e:
            # 此处只是简单地打印异常信息
            print("转换出异常:", e)
            # 再次引发自定义异常
            raise AuctionException("竞拍价必须是数值,不能包含其他字符!")  # ①
            raise AuctionException(e)
        if self.init_price > d:
            raise AuctionException("竞拍价比起拍价低,不允许竞拍!")
        initPrice = d
def main():
    at = AuctionTest(20.4)
    try:
        at.bid("df")
    except AuctionException as ae:
        # 再次捕获到bid()方法中的异常,并对该异常进行处理
        print('main函数捕捉的异常:', ae)
main()

上面程序中 9~13 行代码对应的 except 块捕获到异常后,系统打印了该异常的字符串信息,接着引发一个 AuctionException 异常,通知该方法的调用者再次处理该 AuctionException 异常。所以程序中的 main() 函数,也就是 bid() 方法的调用者还可以再次捕获 AuctionException 异常,井将该异常的详细描述信息打印出来。

这种 except 和 raise 结合使用的情况在实际应用中非常常用。实际应用对异常的处理通常分成两个部分:

应用后台需要通过日志来记录异常发生的详细情况;

应用还需要根据异常向应用使用者传达某种提示;

在这种情形下,所有异常都需要两个方法共同完成,也就必须将 except 和 raise 结合使用。

如果程序需要将原始异常的详细信息直接传播出去,Python 也允许用自定义异常对原始异常进行包装,只要将上面 ① 号代码改为如下形式即可:

raise AuctionException(e)

raise 不需要参数

正如前面所看到的,在使用 raise 语句时可以不带参数,此时 raise 语句处于 except 块中,它将会自动引发当前上下文激活的异常;否则,通常默认引发 RuntimeError 异常。

例如,将上面程序改为如下形式:

class AuctionException(Exception): pass
class AuctionTest:
    def __init__(self, init_price):
        self.init_price = init_price
    def bid(self, bid_price):
        d = 0.0
        try:
            d = float(bid_price)
        except Exception as e:
            # 此处只是简单地打印异常信息
            print("转换出异常:", e)
            # 再次引发自定义异常
            raise
        if self.init_price > d:
            raise AuctionException("竞拍价比起拍价低,不允许竞拍!")
        initPrice = d
def main():
    at = AuctionTest(20.4)
    try:
        at.bid("df")
    except AuctionException as ae:
        # 再次捕获到bid()方法中的异常,并对该异常进行处理
        print('main函数捕捉的异常:', ae)
main()

正如从 13 行代码所看到的,此时程序在 except 块中只是简单地使用 raise 语句来引发异常,那么该 raise 语句将会再次引发该 except 块所捕获的异常。运行该程序,可以看到如下输出结果:

转换出异常: could not convert string to float: 'df'
main 函数捕获的异常:<class 'ValueError'>

从输出结果来看,此时 main() 函数再次捕获了 ValueError,它就是在 bid() 方法中 except 块所捕获的原始异常。

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

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

相关文章

智能配电房解决方案

智能配电房解决方案运用物联网、云计算、大数据、人工智能等先进技术&#xff0c;构建具备遥测、遥信、遥控、遥调、遥视功能的智能配电房&#xff0c;依托电易云-智慧电力物联网实现对配电室的全面感知、智能监控、优化运行、精益管理&#xff0c;提高供电可靠性&#xff0c;降…

系统设计之数据库

为您的项目选择正确的数据库是一项复杂的任务。许多数据库选项都适合不同的用例&#xff0c;很快就会导致决策疲劳。 我们希望这份备忘单提供高级指导&#xff0c;以找到符合您项目需求的正确服务并避免潜在的陷阱。 注意&#xff1a;Google 关于其数据库用例的文档有限。尽管…

笔记本用gpu运行tensorflow-gpu,keras写的老程序,结果与原来不一样,一脸懵逼。

先说结论我笔记一是rtx3050ti, 重点RTX30系列最低要求CUDA版本为11.1&#xff0c;否则最后跑程序会报错。再说现象&#xff0c;突发奇想想在笔记本上运行一个以前在1080titensorflow-gpu1.5.2,keras2.2.4上面写的一个图像分类模型&#xff0c;先用cpu模式 运行一下一切正常。如…

探索正则可视化工具:让编程更直观、高效

导语&#xff1a;在当今的编程世界中&#xff0c;正则表达式已成为不可或缺的技能。然而&#xff0c;理解和编写正则表达式往往是一项具有挑战性的任务。为了降低门槛&#xff0c;提高编程效率&#xff0c;正则可视化工具应运而生。 一、正则表达式的简介与历史 正则表达式&a…

基于JNI实现调用C++ SDK

基于JNI实现调用C SDK 背景分析解决实践 背景 上篇文章总结了几种Java项目调用C/C SDK项目方法&#xff0c;在逐一实践、踩坑后&#xff0c;最终还是敲定采用 JNI 方式进行实现。在文章开始的过程&#xff0c;会先大概讲讲笔者遇到的情况&#xff0c;因为封装方式需要根据实际…

文本润色工具有哪些,高质量的文本润色软件

在当今信息过载的时代&#xff0c;文本的重要性愈发凸显。即便是最精心构思的文章&#xff0c;若未经过仔细的润色&#xff0c;也难以达到最佳的表达效果。本文将专心分享文本润色工具的种类。 文本润色工具的种类 文本润色工具根据其功能和应用范围可以分为多个种类&#xff…

【C语言快速学习基础篇】之二控制语句、循环语句、隐式转换

文章目录 一、控制语句1.1、for循环1.2、while循环1.3、注意&#xff1a;for循环和while循环使用上面等同1.4、do while循环1.4.1while条件成立时1.4.2、while条件不成立时 C语言介绍 C语言是一门面向过程的计算机编程语言&#xff0c;与C、C#、Java等面向对象编程语言有所不同…

python pydoc生成API文档

pydoc是python内置的一个文档生成模块。 pydoc 模块会根据 Python 模块来自动生成文档。 生成的文档可在控制台中显示为文本页面&#xff0c;提供给 Web 浏览器访问或者保存为 HTML 文件。 对于模块、类、函数和方法&#xff0c;显示的文档内容取自文档字符串&#xff08;即 _…

202350读书笔记|《再别康桥:徐志摩诗选》——微风起,清芬酝藉,不减荼

202350读书笔记|《再别康桥&#xff1a;徐志摩诗选》——微风起&#xff0c;清芬酝藉&#xff0c;不减荼 《再别康桥&#xff1a;徐志摩诗选》我觉得有时候诗人是很狂热的&#xff0c;上头的感觉。 有几首很喜欢&#xff0c;节选如下&#xff1a; 偶然 我是天空里的一片云&…

【STM32】TIM定时器输入捕获

1 输入捕获 1.1 输入捕获简介 IC&#xff08;Input Capture&#xff09;输入捕获 输入捕获模式下&#xff0c;当通道输入引脚出现指定电平跳变时&#xff08;上升沿/下降沿&#xff09;&#xff0c;当前CNT的值将被锁存到CCR中&#xff08;把CNT的值读出来&#xff0c;写入到…

JavaScript编程基础 – 闭包(Closure)

JavaScript编程基础 – 闭包 JavaScript Programming Essentials - Closure By JacksonML 闭包和JavaScript的作用域有关。 我们需要先理解闭包的概念。 本文简要介绍闭包函数以及环境状态&#xff0c;并用实例说明闭包的创建及其基本用法。希望对学习及开发有所帮助。 1. …

sql优化常用的几种方法

SQL优化是数据库管理和应用开发中的一个重要环节&#xff0c;它涉及到对SQL查询语句的改进&#xff0c;以提高执行效率&#xff0c;减少系统负载&#xff0c;并优化资源使用。以下是一些常用的SQL优化方法&#xff0c;我会尽量覆盖一些关键的点。 使用合适的数据类型 选择适…

通俗易懂的案例+代码解释AOP 切面编程

目录 1. 理解AOP2 Before2.1 controller层2.2 service层2.3 自定义注解2.4 切面 advice 3 After4 Around spring的三大核心&#xff1a;IOC控制反转、DI依赖注入、AOP面向切面编程 刚开始接触springboot项目&#xff0c;前两个使用的多&#xff0c;亲自使用AOP的机会并不多&…

python自动化测试如何做数据缓存 ?这个第三方包推荐给你,方便又简单!

1.数据缓存说明 数据缓存可以说也是项目开发中比不可少的一个工具 &#xff0c;像我们测试的系统中 &#xff0c;你都会见到像Redis一样的数据缓存库 。使用缓存数据库的好处不言而喻&#xff0c;那就是效率高 &#xff0c;简单数据直接放在缓存中 &#xff0c;存取简单方便 。…

探索Scrapy-spider:构建高效网络爬虫

Spider简介 Scrapy中的Spider是用于定义和执行数据抓取逻辑的核心组件。Spider负责从指定的网站抓取数据&#xff0c;并定义了如何跟踪链接、解析内容以及提取数据的规则。它允许您定制化地指定要抓取的网站、页面和所需的信息。Spider的作用是按照预定的规则爬取网页&#xf…

12.7 C++作业

自由发挥登录窗口的应用场景&#xff0c;实现一个登录窗口界面 #include "widget.h"Widget::Widget(QWidget *parent): QWidget(parent) {//*******窗口相关设置********this->setWindowTitle("王者农药"); //设置窗口标题this->setWindowIcon(QIc…

OpenTiny Vue 3.12.0 发布:文档大优化!增加水印和二维码两个新组件

你好&#xff0c;我是 Kagol。 非常高兴跟大家宣布&#xff0c;2023年11月30日&#xff0c;OpenTiny Vue 发布了 v3.12.0 &#x1f389;。 OpenTiny 每次大版本发布&#xff0c;都会给大家带来一些实用的新特性&#xff0c;10.24 我们发布了 v3.11.0 版本&#xff0c;增加了富…

算法学习系列(六):高精度加法、减法、乘法、除法

目录 引言一、高精度加法1.题目描述2.代码实现3.测试 二、高精度减法1.题目描述2.代码实现3.测试 三、高精度乘法1.题目描述2.代码实现3.测试 四、高精度除法1.题目描述2.代码实现3.测试 引言 本文介绍了高精度加法、高精度减法、高精度乘法、高精度除法&#xff0c;这个高精度…

【Java数据结构 -- List和ArrayList与顺序表】

List和ArrayList与顺序表 一. List1.1 List介绍2.1 常见接口介绍3.1 List的使用 二. ArrayList与顺序表1.线性表2.顺序表2.1 接口的实现 3.ArrayList简介4. ArrayList使用4.1 ArrayList的构造 4.2 ArrayList常见操作4.3 ArrayList的遍历4.4 ArrayList的扩容机制5. ArrayList的具…