• 写给Python社群的第8课:Python异常,你必须掌握的技术点


    ⛳️ 异常是什么

    任何程序都会出错,任何程序员都会写错代码,程序员编写程序一直处于编写,调试的循环中,程序异常也叫做程序BUG,一般情况是代码语法报错,逻辑错误,或者运行环境错误,正式学习异常前还需要提前掌握一句真理。

    异常永远无法避免,我们要做的是尽量减少异常。

    由于异常无法避免,所以需要区分一下异常级别。

    最简单的异常
    语法错误是Python编码过程中最简单的异常,也就是代码语法出错,一般编辑器,即开发工具就会提示出异常信息和异常位置,直接修改即可。该类错误是新手在初学阶段常犯的错误之一。

    隐性错误
    该类异常不好排查,一般是代码有逻辑错误或者缺陷,只有当程序满足某些特定条件的时候,才会触发,例如当程序要求用户输入数字,而我们又没有提前验证,当用户输入非数字字符时,就会报错。

    隐性错误是未来我们检查程序健壮性的主要切入点,因其不容易被发现,且编码过程中编译正常,运行正常,甚至有些错误出现后程序都能正常运行,如果让这样的错误在程序中,并且积累了一段时间,将造成无法修复的重大事故。

    高级错误
    这类错误一般属于不确定性错误,例如打开文件的时候,发现文件被占用(在 windows 上删除 word 文档,或者改名时,就会出现该异常,提示文件被占用),还有程序在传输网络数据的时候,网络突然被中断,手机或者电脑突然死机,这些都属于高级错误,而且充满不确定性,在实战中我们要尽可能的想到这些错误,并提前做好异常处理,这才是本篇博客核心要探究的内容。

    ⛳️ 异常捕获

    我们先从捕获Python程序中异常的通用方法开始学习,即当Python程序出错时,通过何种语法将其捕获到。

    基本异常捕获语句
    首先看一下异常捕获的语法格式。

    try:
    	待捕获异常的语句
    except:
    	捕获异常之后的操作
    
    • 1
    • 2
    • 3
    • 4

    其中关键字 try 表示异常语句的开始,待捕获异常的语句 是可能出现异常的位置,关键字 except 用来捕获异常,并输出错误信息,接下来编写一段异常捕获代码,用于捕获当除数为0时,出现的异常信息

    chushu = 0
    try:
        ret = 10/chushu
        print(ret)
    except:
        print("除数不能为0")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    上述代码中的 chushu 可以切换为0或者其它值,然后查看对应的输出信息。

    除了 tryexcept 两个关键字外,还有 finally 也是异常语句中出现频率较高的关键字,其表示无论程序是否出现异常,都需要执行的代码

    try:
    	待捕获异常的语句
    except:
    	捕获异常之后的操作语句
    finally:
    	无论是否出现异常,这里的代码都要执行
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    修改除数不为零的程序,示例如下:

    chushu = 0
    try:
        ret = 10/chushu
        print(ret)
    except:
        print("除数不能为0")
    finally:
        print("我一直需要执行")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    经过测试也可以得到相应的结论,即 finally 语句无论程序是否出现异常,都会执行。

    这里再扩展一个知识点,finally 语句具备强制性,即当程序被退出时,也要执行完毕 finally 中的代码,才会退出。
    下述代码需要用到 sys 对象的退出方法 exit()

    import sys
    chushu = 1
    try:
        ret = 10/0
        print(ret)
        
    except:
        print("除数不能为0")
        sys.exit()
    finally:
        print("我一直需要执行")
    
    print("我无法被执行到了")
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    输出信息比较多,这里截图给大家展示,可以看到即使程序出错时被强制结束,finally 也继续执行。
    在这里插入图片描述

    ⛳️ 异常类型

    本小节时本篇博客的重点,就是异常类型,关键点为 except 语句,其后可以捕获特定异常信息,在前文图片中,如果你细心观察,会发现一个单词 ZeroDivisionError ,翻译一下表示除数不能为零,这就是错误类型,常见的错误类型如下所示。

    • ValueError:值错误;
    • IndexError:索引错误,例如在列表读取的时候,经常碰到该错误类型;
    • SyntaError:语法错误,最常见的错误,编译器无法执行的代码,都会展示该错误;
    • NameError:对象名不存在,例如直接运行该代码 print(name),就会出现该错误类型的提示;
    • KeyError:操作字典时,Key 不存在;
    • TypeError:数据类型错误;
    • ModuleNoFoundError:导入模块错误;
    • AttributeError:属性错误。

    这些都属于常见错误,Python 内置的错误类型远远不止这些,如果希望学习更多,可以直接搜索 Python 异常类型,然后学习更多资料,使用 except 捕获特定异常的操作如下所示。

    try:
        print(name)
    except NameError as n:
        print(n)
    
    • 1
    • 2
    • 3
    • 4

    重点查看 except NameError as n:,其 except 关键字后跟的就是异常类型,as 是重命名的含义,所以 n 就表示捕获到的 NameError 对象。
    输出 n,也就输出了错误信息。

    except 还可以支持多次捕获,代码如下。

    try:
        print(name)
    except NameError as n:
        print("NameError")
        print(n)
    except Exception as n:
        print("Exception")
        print(n)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    这里执行顺序是:优先进入捕获到异常类型的语句中,执行操作,所以得到的输出如下所示。

    NameError
    name 'name' is not defined
    
    • 1
    • 2

    前文的代码中,还出现了一个未罗列的异常类型,即 Exception,该类是所有异常的类的基类(父类),所以当你不能百分百明确异常类型的时候,可以含糊的使用 Exception

    ⛳️ raise 抛出异常

    实际工作中碰到的项目,有时候需要手动抛出异常,这就需要用到 raise 关键字了,其语法格式如下。

    raise '异常信息'
    
    • 1

    使用的时候可以携带异常信息,也可以忽略,代码如下。

    def show_exception():
        raise 
        
    def show():
        raise '抛出异常'
    show()
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    直接运行代码,会出现类型错误,即 TypeError: exceptions must derive from BaseException,该异常表示 raise 关键字抛出的异常,未指定异常类型,进行一下简单修改,即可完美运行,代码如下。

    def show():
        raise Exception('抛出异常')
    show()
    
    • 1
    • 2
    • 3

    📢📢📢📢📢📢
    💗 你正在阅读 【梦想橡皮擦】 的博客
    👍 阅读完毕,可以点点小手赞一下
    🌻 发现错误,直接评论区中指正吧
    📆 橡皮擦的第 746 篇原创博客

    从订购之日起,案例5年内保证更新

  • 相关阅读:
    请按规范写Python
    一篇文章搞定Redis Stream
    C++ 入门
    vue制作自己的组件库(仿ElementUI)
    autojs(意图篇之startActivity)
    2022年7月Web3行业月度发展报告区块链篇 | 陀螺科技会员专享
    ES6 新增功能复盘梳理
    React脚手架介绍和Demo
    ConstraintTools...
    原型设计模式
  • 原文地址:https://blog.csdn.net/hihell/article/details/127739138