044.Python异常处理_手动抛出异常自定义异常

无奋斗不青春

我 的 个 人 主 页:👉👉 失心疯的个人主页 👈👈
入 门 教 程 推 荐 :👉👉 Python零基础入门教程合集 👈👈
虚 拟 环 境 搭 建 :👉👉 Python项目虚拟环境(超详细讲解) 👈👈
PyQt5 系 列 教 程:👉👉 Python GUI(PyQt5)文章合集 👈👈
Oracle数据库教程:👉👉 Oracle数据库文章合集 👈👈
优 质 资 源 下 载 :👉👉 资源下载合集 👈👈

分隔线

手动抛出异常&自定义异常

    • raise手动抛出异常
      • raise语句
    • assert 断言
      • 概念
      • 语法
    • 自定义异常

raise手动抛出异常

raise语句

  • 之前我们遇到的都是系统检测到一些特定的错误场景之后,自动的像外界抛出的异常,我们只需要使用try...except语句或with语句解决这些异常就可以了
  • 本节学习的是通过raise语句手动抛出指定类型的异常
  • 应用场景
    • 比如,我们写了一个库(模块),里面定义了很多函数
    • 当外界用户调用库里面的函数时,传入的值不满足条件的时候,我们就可以抛出异常。用户可以通过try...except语句或with语句来捕获这个异常来进行处理
    • 大家可能在想,我们在函数内部直接用try...except语句对这种错误进行容错处理不就行了么
      • 1、我们的库可能会有很多人使用,每个人每种情况对这个异常的处理方法都可能不一样,如果在函数内用try...except语句处理,那就固定死了
      • 2、有时候在函数内部并没有出现异常,根本无法用try...except语句进行捕获处理
        def set_age(age):
            print(f'张三的年龄是:{age}')
            
        
        # 比如别人调用这个函数的时候,我这里的age必须要大于0,那么他传入一个-10,函数内部并不会出现异常,也就无法通过`try...except`语句是进行捕获的
        
    • 是不是考虑可以加上条件判断,不满足条件则通过return返回一个固定值呢?
      • 来一个简单的实例看一下
      def test(a, b):
          if a <= b:
              return -1    
          return a - b
          
      # 这个函数调用的时候,要求a必须大于b,如果用return的方法,那当a<b的时候,返回一个-1
      # 那到底是不满足条件返回的-1,还是计算结果是-1呢?这就容易让人产生误解
      
    • 类似于诸多场景,我们就可以通过raise语句手动抛出异常,让用户知道出错了,并且可以捕获到这个异常,进行各自个性化的处理
  • 语法
    raise [Exception [, args [, traceback]]]
    
    # Exception     # 引发的异常类或异常对象
    # args          # 异常的参数
    # traceback     # 异常的跟踪信息
    
  • 引发内置异常
    raise ValueError("这是一个ValueError异常")
    
  • 引发自定义异常
    class MyException(Exception):
        pass
    
    raise MyException("这是一个自定义异常")
    
  • 示例
  • 示例1:
  • 如果只想知道是否抛出了一个异常,并不想去处理它,那么一个简单的raise语句就可以把它抛出
    def test(num):
        if num < 0:
            raise
        print(num)
    
    
    test(-10)
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\05-抛出异常.py", line 8, in <module>
        test(-10)
      File "E:\StudyCode\Python\14-异常处理\05-抛出异常.py", line 4, in test
        raise
    RuntimeError: No active exception to reraise
    
    Process finished with exit code 1
    
  • 示例2:
  • raise语句的唯一一个参数可以指定要被抛出的异常对象。它必须是一个异常的实例或者是异常的类
  • 我们可以通过这个指定的抛出的异常对象来捕获这个异常
    def set_age(age):
        if age <= 0 or age > 200:
            raise ValueError
        print(age)
    
    try:
        set_age(-10)
    except ValueError as e:
        print('age参数传值超出范围', e)
        
    
    # ========== 输出结果 ==========
    # age参数传值超出范围 
    
    • 这里的输出结果可以看到仅仅只是打印了我们指定的字符串,错误对象e并没有输入任何内容
  • 示例3:raise语句可以给异常对象添加参数,对这个异常进行说明,让使用者更加清晰是什么原因产生的异常
    def set_age(age):
        if age <= 0:
            raise ValueError('值小于0了!')
        elif age > 200:
            raise ValueError('值大于200了!')
        print(age)
    
    try:
        set_age(-10)
    except ValueError as e:
        print('age参数传值超出范围1:', e)
    
    try:
        set_age(310)
    except ValueError as e:
        print('age参数传值超出范围2:', e)
    
    
    # ========== 输出结果 ==========
    # age参数传值超出范围1: 值小于0了!
    # age参数传值超出范围2: 值大于200了!
    


assert 断言

概念

  • assert 断言用于判断一个表达式,在表达式条件为False的时抛出AssertionError异常
  • 断言可以在条件不满足程序运行的情况下直接返回错误,而不必等待程序运行后出现崩溃的情况的时候触发异常

语法

  • assert语法
    # 不带参数
    assert expression
    
    # 带参数
    assert expression, arguments
    
    
    # assert        # assert关键字
    # expression    # 表达式,表达式结果为True不抛出异常,结果为Fasle则抛出异常
    # arguments     # 参数,用于对异常的描述
    
  • 等同于
    # 不带参数
    if not expression:
        raise AssertionError
    
    # 带参数
    if not expression:
        raise AssertionError(arguments)
    
  • 示例
  • 示例1:不带参数
    def set_age(age):
        assert age > 0
        print(f'为张三设置的年龄是:{age}')
    
    
    
    set_age(-20)
    
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\06-assert断言.py", line 8, in <module>
        set_age(-20)
      File "E:\StudyCode\Python\14-异常处理\06-assert断言.py", line 3, in set_age
        assert age > 0
    AssertionError
    
  • 示例2:带参数
    def set_age(age):
        assert age > 0, '年龄设置太小了!'
        print(f'为张三设置的年龄是:{age}')
    
    
    
    set_age(-20)
    
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\06-assert断言.py", line 8, in <module>
        set_age(-20)
      File "E:\StudyCode\Python\14-异常处理\06-assert断言.py", line 3, in set_age
        assert age > 0, '年龄设置太小了!'
    AssertionError: 年龄设置太小了!
    


自定义异常

  • 前面我们所有手动抛出的异常类都是系统内置的ValueError,如果我们需要抛出一个我们自己异常类呢?

  • 示例

    def set_age(age):
        if age <= 0:
            raise SxfError
    
        print(age)
    
    
    set_age(-10)
    
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 8, in <module>
        set_age(-10)
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 3, in set_age
        raise SxfError
    NameError: name 'SxfError' is not defined
    
  • 这里输出结果提示我们名称错误:没有定义名称 SxfError

  • 那么,我们先定义一个,这是一个异常类,所以我们需要定义一个类,再使用

    class SxfError:
        pass
    
    def set_age(age):
        if age <= 0:
            raise SxfError
    
        print(age)
    
    
    set_age(-10)
    
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 11, in <module>
        set_age(-10)
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 6, in set_age
        raise SxfError
    TypeError: exceptions must derive from BaseException
    
  • 定义类之后,依然报错了。提示我们类型错误:异常必须派生自BaseException

  • 我们回顾一下前面所学的异常,里面讲到了BaseException是所有内建异常的基类

    # BaseException                 # 所有内建异常的基类
        # SystemExit                # 由sys.exit()函数引发,当它不处理时,Python解释器退出
        # KeyboardInterrupt         # 当用户点击中断键时引发
        # GeneratorExit             # 当调用一种generator的close()方法时引发
        # Exception                 # 所有内置的、非系统退出异常都是从该类派生的(所有自定义异常都应该继承自该类)
    
  • 这里可以看到SystemExit是系统退出引发的异常类型,KeyboardInterrupt是用户按键引发的异常类型,GeneratorExit是关闭操作是引发的异常类型;而我们自定义的明显都不属于这几种操作,所以我们可以让自定义异常继承自Exception这个异常类

  • Exception类是继承自BaseException类,自定义类再继承自Exception类;那么,自定义类也就间接的继承自BaseException类了

  • 那我们尝试一下

    class SxfError(Exception):
        pass
    
    
    def set_age(age):
        if age <= 0:
            raise SxfError
    
        print(age)
    
    
    set_age(-10)
    
    
    # ========== 输出结果 ==========
    Traceback (most recent call last):
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 11, in <module>
        set_age(-10)
      File "E:\StudyCode\Python\14-异常处理\06-自定义异常.py", line 6, in set_age
        raise SxfError
    __main__.SxfError
    
  • 诶…好像成功了,下面抛出了异常,明显不再是前面的类型错误异常了,我们利用try...except语句捕获一下看看

    class SxfError(Exception):
        pass
    
    
    def set_age(age):
        if age <= 0:
            raise SxfError
    
        print(age)
    
    
    try:
        set_age(-10)
    except SxfError as e:
        print('出错啦!捕获到异常了!', e)
        
    
    # ========== 输出结果 ==========
    # 出错啦!捕获到异常了!
    
  • 不错,异常捕获成功了!但是我们通过这个异常对象并没有拿到任何异常相关的信息

  • 那么,我们可以通过传递参数来自定义异常的信息,以更准确地描述出现异常的原因和上下文。

  • 在抛出异常时,可以将参数传递给异常类,供后续处理程序使用,那么我们在定义异常类的时候就需要添加__init__()方法来接收实例化对象时传递过来的实参了

  • 示例代码:

    class SxfError(Exception):
        def __init__(self, ErrorValue):
            self.ErrorValue = ErrorValue
        pass
    
    
    def set_age(age):
        if age <= 0:
            raise SxfError('值小于0了!')
    
        print(age)
    
    
    try:
        set_age(-10)
    except SxfError as e:
        print('出错啦!', e.ErrorValue)
        
        
    # ========== 输出结果 ==========
    # 出错啦! 值小于0了!
    
  • 哈哈,这里我们通过对象的ErrorValue属性就可以拿到这个错误提示了,但是明显和我们使用内置的异常类不一样,内置的异常类只需要直接打印这个对象就可以输出这个异常提示了

  • 回顾一下面向对象的内容,里面有一个__str__方法,在访问实例对象时会自动调用

  • 关于面向对象__str__方法

  • 那么,我们可以在类里面定义这个方法,并输出我们想要的内容

    class SxfError(Exception):
        def __init__(self, ErrorValue, ErrorCode=None):
            self.ErrorValue = ErrorValue
            self.ErrorCode = ErrorCode
    
        def __str__(self):
            return str(self.ErrorValue) + ' ' + str(self.ErrorCode)
    
    
    def set_age(age):
        if age <= 0:
            raise SxfError('值小于0了!', 404)
    
        print(age)
    
    
    try:
        set_age(-10)
    except SxfError as e:
        print('出错啦!', e)
        
        
    # ========== 输出结果 ==========
    # 出错啦! 值小于0了! 404
    
  • 这个就跟内置异常类型差不多啦!

  • 其实,这个自定义异常就是一个自定义类,其他操作完全可以参照前面所学的面向对象相关内容

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

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

相关文章

ubuntu 磁盘挂载

1.前提 给自己的计算机加了一个新硬盘&#xff0c;怎么在ubuntu中使用呢 特别提示&#xff01;对磁盘操作存在一定丢失数据的风险&#xff0c;本篇是在一个新购买的硬盘上进行操作&#xff01;如果你使用的是一个带数据的硬盘&#xff0c;请勿参考本篇文章&#xff01; 2.找…

解决:AttributeError: module ‘scipy.misc’ has no attribute ‘imread’

解决&#xff1a;AttributeError: module ‘scipy.misc’ has no attribute ‘imread’ 文章目录 解决&#xff1a;AttributeError: module scipy.misc has no attribute imread背景报错问题报错翻译报错位置代码报错原因解决方法方法一 scipy版本回退&#xff08;不推荐&#…

记录 | Visual Studio报错:const char*类型的值不能用于初始化char*类型

Visual Studio 报错&#xff1a; const char *”类型的值不能用于初始化“char *”类型的实体错误 解决办法&#xff1a; 1&#xff0c;强制类型转换&#xff0c;例如&#xff1a; char * Singer::pv[] {(char*)"other", (char*)"alto", (char*)"c…

会旋转的树,你见过吗?

&#x1f388;个人主页:&#x1f388; :✨✨✨初阶牛✨✨✨ &#x1f43b;强烈推荐优质专栏: &#x1f354;&#x1f35f;&#x1f32f;C的世界(持续更新中) &#x1f43b;推荐专栏1: &#x1f354;&#x1f35f;&#x1f32f;C语言初阶 &#x1f43b;推荐专栏2: &#x1f354;…

工业数据的特殊性和安全防护体系探索思考

随着工业互联网的发展&#xff0c;工业企业在生产运营管理过程中会产生各式各样数据&#xff0c;主要有研发设计数据、用户数据、生产运营数据、物流供应链数据等等&#xff0c;这样就形成了工业大数据&#xff0c;这些数据需要依赖企业的网络环境和应用系统进行内外部流通才能…

字体包引入以及使用

将UI给的字体包下载到assets文件夹下 app.vue全局定义 <style> * {margin: 0;padding: 0; }font-face {font-family: PangMenZhengDao-3;src: url(/assets/fonts/庞门正道标题体3.0.TTF) format(truetype);font-weight: bold;font-style: normal; } </style>页面使…

亚马逊云科技re:Invent推出生成式AI技术堆栈及关键服务和工具

亚马逊云科技于29日推出“生成式AI技术堆栈”后&#xff0c;又在30日的re:Invent 2023大会上宣布了一系列支持这一全新堆栈的关键服务和工具。 亚马逊云科技数据和人工智能副总裁Swami Sivasubramanian在主题演讲中&#xff0c;将生成式人工智能与“超新星爆炸”进行了比较&am…

ffmpeg可以做什么

用途 FFmpeg是一个功能强大的多媒体处理工具&#xff0c;可以处理音频和视频文件。它是一个开源项目&#xff0c;可在各种操作系统上运行&#xff0c;包括Linux、Windows和Mac OS X等。以下是FFmpeg可以做的一些主要任务&#xff1a; 转换媒体格式&#xff1a;可将一个媒体格式…

云原生基础入门概念

文章目录 发现宝藏云原生的概念云原生的关键技术为何选择云原生&#xff1f;云原生的实际应用好书推荐 发现宝藏 前些天发现了一个巨牛的人工智能学习网站&#xff0c;通俗易懂&#xff0c;风趣幽默&#xff0c;忍不住分享一下给大家。【宝藏入口】。 云原生的概念 当谈及现…

http跟https的区别

只要上过网的朋友一定接触过“HTTP”&#xff0c;每次开网页的时候&#xff0c;不管是什么网址&#xff0c;其前面都会出现HTTP字样&#xff0c;比如 “http&#xff1a;55049sjad.com”、“http&#xff1a;544.65.5.6.com”等等&#xff0c;而有些时候打开如银行等对安全性要…

【linux】SSH终端Putty配置:文件上传/下载、显示中文字体、自动登录

文章目录 写在前面putty上传/下载文件1. 下载2. 解压和配置3. 使用sz/rz3.1 下载文件:sz3.2 上传文件:rz 显示中文字体1. 下载合适的字体2. 解压和安装3. putty配置 putty自动登录1. putty配置2. putty快捷方式配置3. 使用putty 写在后面 写在前面 一篇博客介绍了12种SSH终端工…

D3132|贪心算法

435.无重叠区间 初始思路&#xff1a; 我的思路就是如果有两个区间重叠&#xff0c;保留end比较小的那个区间&#xff0c;删除end比较大的区间。 class Solution {public int eraseOverlapIntervals(int[][] intervals) {Arrays.sort(intervals, new Comparator<int[]>…

恐怖题材黑马大作,艾尔莎B760M-E D5和你玩转《心灵杀手2》

说起恐怖题材的游戏&#xff0c;相信不少朋友都会第一时间想到《生化危机》、《寂静岭》、《死亡空间》等经典系列与作品。而在最近这几年&#xff0c;恐怖题材游戏也有不少黑马出现&#xff0c;比如最近推出的《心灵杀手2》就是2010年《心灵杀手》的续作&#xff0c;它是由开发…

iPhone16:首款AI iPhone?

随着科技水平的不断发展&#xff0c;智能手机逐渐成为人们最依赖的电子产品之一。为能够满足用户需求&#xff0c;手机的硬件、外观设计与性能飞速提升&#xff0c;这也导致智能手机市场快速进入到瓶颈期。 为了能够带来更优秀的表现&#xff0c;苹果可能会为iPhone 16系列带来…

中国首家!腾讯云入选Gartner®视频平台服务市场指南代表厂商

近日&#xff0c; Gartner正式发布《Market Guide for Video Platform Services》&#xff08;《视频平台服务市场指南》&#xff0c;下称“《指南》”&#xff09;&#xff0c;凭借领先的音视频技术和产品组合优势&#xff0c;腾讯云成为中国首家且唯一入选的代表厂商。 腾讯…

GZ015 机器人系统集成应用技术样题8-学生赛

2023年全国职业院校技能大赛 高职组“机器人系统集成应用技术”赛项 竞赛任务书&#xff08;学生赛&#xff09; 样题8 选手须知&#xff1a; 本任务书共 25页&#xff0c;如出现任务书缺页、字迹不清等问题&#xff0c;请及时向裁判示意&#xff0c;并进行任务书的更换。参赛队…

Vue学习笔记-Vue3中的customRef

作用 创建一个自定义的ref&#xff0c;并对其依赖项的更新和触发进行显式控制 案例 描述&#xff1a;向输入框中输入内容&#xff0c;在下方延迟1秒展示输入内容 代码&#xff1a; <template><input type"text" v-model"keyword"><h3&…

力扣刷题记录(15)LeetCode:509、70、746

目录 509.斐波那契数 70.爬楼梯 746.使用最小花费爬楼梯 总结 ​​​​​​ 用一个数组来存储前两个数的值&#xff0c;然后根据前两个数的值来确定当前的值。 class Solution { public:int fib(int n) {if(n<2) return n;vector<int> v;v.push_back(0);v.push…

3 使用postman批量创建测试数据

上一篇:2 使用postman进行接口测试-CSDN博客 在软件测试实际工作中,因测试需要,我们要批量创建测试数据。如果某些接口不允许输入重复数据,我们在做批量请求时就要做参数处理了。 比如在上一篇介绍的用户注册接口,一般注册的时候用户名是不允许重复的,如果要批量创…

8.完成任务实现的SDK封装及插件式加载

1.设计 任务的实现目前完成了Modbus RTU、Modbus TCP、Virtule。任务实现应该是任意的&#xff0c;比如打印一段话&#xff0c;执行一句SQL等&#xff0c;所以系统内部的必然要做到可扩展。 要做到可扩展&#xff0c;首先第一步就是定义标准&#xff0c;所以我们首先需要封装…
最新文章