Python程序异常处理

2023-11-19

一、什么是异常

异常就是程序运行时发生错误的信号,在程序由于某些原因出现错误的时候,若程序没有处理它,则会抛出异常,程序也的运行也会随之终止;

  • 程序异常带来的问题:

1.程序终止,无法运行下去;  2…如果程序是面向客户,那么会使客户的体验感很差,进而影响业务;

  • 什么时候容易出现异常:

当处理不确定因素时,比如有用户参与,有外界数据传入时,都容易出现异常;

  • 产生异常事件大致分两种:
    1.由于语法错误导致程序出现异常,这种错误,根本过不了Python解释器的语法检查,必须在程序执行前就改正;
#语法错误示范一:
if

#语法错误示范二:
def func:

#语法错误示范三:
class foo
    pass

#语法错误示范四:
print(hello word

2.就是由于代码的逻辑问题使程序产生了异常;

#错误示例:
for n in 3:
    pass

#错误示例:
[][1]

二、异常的类型

异常也是有分类的,不同的异常用不同的类型去标识,不同的类对象标识不同的异常,一个异常标识一种错误;

常用的异常种类:

'''
AttributeError            #试图访问一个对象没有的树形,比如foo.x,但是foo没有属性x
IOError                      # 输入/输出异常;基本上是无法打开文件
ImportError               #无法引入模块或包;基本上是路径问题或名称错误
IndentationError        #语法错误(的子类) ;代码没有正确对齐
IndexError                 #下标索引超出序列边界,比如当x只有三个元素,却试图访问x[5]
KeyError                     #试图访问字典里不存在的键
KeyboardInterrupt      #Ctrl+C被按下
NameError                  #使用一个还未被赋予对象的变量
SyntaxError                #Python代码非法,代码不能编译,其实是语法错误;
TypeError                    #传入对象类型与要求的不符合
UnboundLocalError      #试图访问一个还未被设置的局部变量,基本上是由于另有一个同名的全局变量,导致你以为正在访问它
ValueError                   #传入一个调用者不期望的值,即使值的类型是正确的

'''                    

在这里插入图片描述

三、异常处理机制

先来看看程序异常后,怎么报的错,我们从报错中能够分析出什么。
在这里插入图片描述

什么是异常处理?

python解释器检测到错误,触发异常(也允许程序员自己触发异常),程序员编写特定的代码,专门用来捕获这个异常(这段特点代码与逻辑程序无关和异常处理有关);如果捕获成功则进入另一个处理分支,执行为其定制的逻辑,使程序不会崩溃,这就是异常处理。

为什么要进行异常处理?

python解释器去执行程序,检测到一个错误时,触发异常,异常触发后且没有被处理的情况下,程序就在当前异常处停止运行,后面的代码不会执行,那么没有人会去使用一个运行着突然就崩溃的软件的;所以我们有必要提供一种异常处理机制来增强程序的健壮性和容错性。

如何进行异常处理?

首先须知,异常是由程序的错误引起的,语法上的错误跟异常处理无关,必须在程序运行前就修正;

1.使用if判断式
num1=input('>>: ') #输入一个字符串试试
int(num1)

使用if判断进行异常处理

num1=input('>>: ') #输入一个字符串试试
if num1.isdigit():
    int(num1) #我们的正统程序放到了这里,其余的都属于异常处理范畴
elif num1.isspace():
    print('输入的是空格,就执行我这里的逻辑')
elif len(num1) == 0:
    print('输入的是空,就执行我这里的逻辑')
else:
    print('其他情情况,执行我这里的逻辑')

问题一:
使用if的方式我们只为第一段代码加上了异常处理,但这些if,跟你的代码逻辑并无关系,这样你的代码会因为可读性差而不容易被看懂

问题二:
这只是我们代码中的一个小逻辑,如果类似的逻辑多,那么每一次都需要判断这些内容,就会倒置我们的代码特别冗长。

小结:

1.if判断式的异常处理只能针对某一段代码,对于不同的代码段的相同类型的错误你需要写重复的if来进行处理;

2.在你的程序中频繁的写与程序本身无关,与异常处理有关的if,会使得你的代码可读性极其的差;

3.if是可以解决异常的,只是存在1,2的问题,所以,千万不要妄下定论if不能用来异常处理;

之前用来判断异常的方法,比如不能输入数字或字母等等

def test():
    print('test running')
choice_dic={
    '1':test
}
while True:
    choice=input('>>: ').strip()
    if not choice or choice not in choice_dic:continue #这便是一种异常处理机制啊
    choice_dic[choice]()
2.python为每一种异常定制了一个类型,然后提供了一种特定的语法结构来进行异常处理;

首先重要的几种搭配格式列出来:

try ... except

try ... except ... else

try ... finally

try ... except ... finally

try ... except ... else ... finally
1)基本语法

异常处理的基本语法

try:
     被检测的代码块
except 异常类型:
     try中一旦检测到异常,就执行这个位置的逻辑

异常处理例子

try:
    a = "A"
    b
except NameError:
    print("b没有赋值会引发程序异常,异常类型时NameError,我们通过"
          "捕获这个异常,使其不会崩溃,继而执行此分支,也就是当前"
          "打印的这段话")

---------------------  运行后的效果 ----------------------------------------------
b没有赋值会引发程序异常,异常类型时NameError,我们通过捕获这个异常,使其不会崩溃,继而执行此分支,也就是当前打印的这段话
2)异常类只能用来处理指定的异常情况,如果非指定异常则无法处理;
try:
    a = "A"
    b
except IndexError:
    print("b没有赋值会引发程序异常,异常类型时NameError,我们通过"
          "捕获这个异常,使其不会崩溃,继而执行此分支,也就是当前"
          "打印的这段话")

-------------------- 运行后的效果  -----------------------------------------------
Traceback (most recent call last):
  File "E:/python/s15/异常处理.py", line 3, in <module>
    b
NameError: name 'b' is not defined

因为我们设置的捕获异常类和其发生异常的类不是一个类,所以捕获不到;

3)多分支

说明:从上向下报错的代码只要找到一个和报错类型相符的分支就执行这个分支中的代码,然后直接退出分支;如果找不到能处理和报错类型相同的分支,会一直往下走,最后还是没有找到就会报错。

多分支异常处理

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)

这里我们需要知道的是as的已是就是将捕获到的异常的内容赋值给变量e,变量e是不固定的,也可以使用其他字母来代替,这样的话,既方便我们对异常的内容进行分析,也不影响程序的执行。

4)多分支合并

说明:如果说我们有多个异常在处理时需要共同处理,比如说,只要发生IndexError和NameError异常了,我们就执行或打印一段代码时,就可以使用多分支合并的方式了;

多分支合并例子

l = ['login','register']
for num,i in enumerate(l,1):
     print(num,i)

  try:
     num = int(input('num >>>'))
     print(l[num - 1])
  except (ValueError,IndexError) :
     print('您输入的内容不合法')
5)万能异常;

说明:在python的异常中,有一个万能异常:Exception,它可以捕获任意异常;

s1 = 'hello'
try:
    int(s1)
except Exception as e:
    print(e)

注意:万能异常应该分两种情况去看;

  • 如果想要的效果是,无论出现什么异常,我们统一丢弃,或者使用同一段代码逻辑去处理他们,那么只有一个Exception就足够了。

  • 如果你想要的效果是,对于不同的异常我们需要定制不同的处理逻辑,那就需要用到多分支了

多分支+Exception

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
except Exception as e:
    print(e)
6)as用法:

说明:能够将具体错误信息打印出来,赋值给变量;

7)异常的其他机构,else,finally;

else 说明:当try内的代码块没有报错时并且还要继续运行程序的话就用else;

finally 说明:无论try内的代码块是否异常,都执行该区域内的代码,通过用来进行清理工作;尤其注意如果在函数中有finally,即使return也会先执行fianlly中的代码。

else 以及 finally

s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)
#except Exception as e:
#    print(e)
else: #Python小白交流学习群:711312441
    print('try内代码块没有异常则执行我')
finally:
    print('无论异常与否,都会执行该模块,通常是进行清理工作')
8)主动触发异常 raise;

说明:这是给开发者用的,比如我们现在用的python,作者就会在python中加入主动触发异常,就是用来给开发者的,当遇到异常时会报错,提示开发者;

>>> try:
...     raise TypeError('类型错误')
... except Exception as e:
...     print(e)
... 
类型错误
9)断言 语法

说明:assert断言语句用来声明某个条件是真的,其作用是测试一个条件(condition)是否成立,如果不成立,则抛出异常。

语法:assert condition

如果condition为false,就raise一个AssertionError出来。逻辑上等同于:

if not condition:
    raise AssertionError()

assert condition,expression

如果condition为false,就raise一个描述为 expression 的AssertionError出来。逻辑上等同于:

if not condition:
        raise AssertionError(expression)

使用例子:

assert 断言例子

>>> assert 1 == 1
>>> assert 1 == 2
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError
>>> assert 1 == 2,"这是什么鬼"
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AssertionError: 这是什么鬼
10)自定义异常

在我们自定义返回异常时,最好使用异常code + 异常data的方式;看一个例子:

#去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。
#code值+data
#1000,成功
#1001,文件不存在
#1002,关键字为空
#1003,未知错误

#方法一:
import os
def func(path,prev):
    """
    去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。
        1000,成功
        1001,文件不存在
        1002,关键字为空
        1003,未知错误
        ...
    :return:
    """
    response = {'code':1000,'data':None}
    try:
        if not os.path.exists(path):
            response['code'] = 1001
            response['data'] = '文件不存在'
            return response
        if not prev:
            response['code'] = 1002
            response['data'] = '关键字为空'
            return response
        pass  #业务代码区
    except Exception as e:
        response['code'] = 1003
        response['data'] = '未知错误'
    return response



#方法二:
import os

class ExistsError(Exception):
    pass

class KeyInvalidError(Exception):
    pass

def new_func(path,prev):
    """
    去path路径的文件中,找到前缀为prev的一行数据,获取数据并返回给调用者。
        1000,成功
        1001,文件不存在
        1002,关键字为空
        1003,未知错误
        ...
    :return:
    """
    response = {'code':1000,'data':None}
    try:
        if not os.path.exists(path):
            raise ExistsError()

        if not prev:
            raise KeyInvalidError()
        pass
    except ExistsError as e:
        response['code'] = 1001
        response['data'] = '文件不存在'
    except KeyInvalidError as e:
        response['code'] = 1002
        response['data'] = '关键字为空'
    except Exception as e:
        response['code'] = 1003
        response['data'] = '未知错误'
    return response



##方法三:
class MyException(Exception):
    def __init__(self,code,msg):
        self.code = code
        self.msg = msg
try:  #Python小白交流学习群:711312441
    raise MyException(1000,'操作异常')
    pass
except KeyError as obj:
    print(obj,1111)
except MyException as obj:
    print(obj,2222)
except Exception as obj:
    print(obj,3333)
----------------------- 打印结果 -------------------------------------------
(1000, '操作异常') 2222
try方式比较if的方式的好处:

try…except这种异常处理机制就是取代if那种方式,让你的程序在不牺牲可读性的前提下增强健壮性和容错性,异常处理中为每一个异常定制了异常类型(python中统一了类与类型,类型即类),对于同一种异常,一个except就可以捕捉到,可以同时处理多段代码的异常(无需‘写多个if判断式’)减少了代码,增强了可读性 ;

使用try…except的方式:

  • 把错误处理和真正的工作分开来

  • 代码更易组织,更清晰,复杂的工作任务更容易实现

  • 毫无疑问,更安全了,不至于由于一些小的疏忽而使程序意外崩溃了

什么时候用异常处理?

try…except应该尽量少用,因为它本身就是你附加给你的程序的一种异常处理的逻辑,与你的主要的工作是没有关系的

这种东西加的多了,会导致你的代码可读性变差,只有在有些异常无法预知的情况下,才应该加上try…except,其他的逻辑错误应该尽量修正

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python程序异常处理 的相关文章

  • 在 python 的 Visual Studio 工具中按下 ctrl+F5 后,控制台窗口立即关闭

    我已经安装了 Visual Studio 的 Python 工具 但在控制台窗口中看不到输出 就像我在 Visual Studio 中运行 C 控制台应用程序时按以下快捷键时看到的输出一样 F5 开始调试程序并关闭 C 和 Python 中
  • 使用Python的工业视觉相机[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 如何 json_normalize() df 中的特定字段并保留其他列? [复制]

    这个问题在这里已经有答案了 这是我的简单示例 我的实际数据集中的 json 字段非常嵌套 因此我一次解压一层 我需要在 json normalize 之后保留数据集上的某些列 https pandas pydata org docs ref
  • 蟒蛇 |如何将元素随机添加到列表中

    有没有一种方法可以将元素随机添加到列表中 内置函数 ex def random append lst a lst append b lst append c lst append d lst append e return print ls
  • Pytest:如何使用从夹具返回的列表来参数化测试?

    我想使用由固定装置动态创建的列表来参数化测试 如下所示 pytest fixture def my list returning fixture depends on other fixtures return a dynamically
  • 如何从网站中提取冠状病毒病例?

    我正在尝试从网站中提取冠状病毒 https www trackcorona live https www trackcorona live 但我得到了一个错误 这是我的代码 response requests get https www t
  • 如何在 openpyxl 中设置或更改表格的默认高度

    我想通过openpyxl更改表格高度 并且我希望首先默认一个更大的高度值 然后我可以设置自动换行以使我的表格更漂亮 但我不知道如何更改默认高度 唯一的到目前为止 我知道更改表格高度的方法是设置 row dimension idx heigh
  • 基于 True/False 值的 Python 优雅赋值

    我想根据三个布尔值中的值设置一个变量 最直接的方法是 if 语句后跟一系列 elif if a and b and c name first elif a and b and not c name second elif a and not
  • 一起使用 Argparse 和 Json

    我是 Python 初学者 我想知道 Argparse 和 JSON 是否可以一起使用 说 我有变量p q r 我可以将它们添加到 argparse 中 parser add argument p param1 help x variabl
  • 如何使用注释和聚合在 Django 的 ORM 中执行此 GROUP BY 查询

    我真的不知道如何翻译GROUP BY and HAVING到姜戈的QuerySet annotate and QuerySet aggregate 我正在尝试将这个 SQL 查询转换为 ORM 语言 SELECT EXTRACT year
  • 别碰我的女人

    我讨厌的一件事迪斯图尔斯 http docs python org distutils 我猜他是邪恶的人 他这样做了 https github com python cpython blob 300dd552b15825abfe0e367a
  • 从 python 中的缩进文本文件创建树/深度嵌套字典

    基本上 我想迭代一个文件并将每行的内容放入一个深层嵌套的字典中 其结构由每行开头的空格数量定义 本质上 目标是采取这样的事情 a b c d e 并将其变成这样的东西 a b c d e Or this apple colours red
  • 如何获取 Matplotlib 生成的散点图的像素坐标?

    我使用 Matplotlib 生成散点图的 PNG 文件 现在 对于每个散点图 除了 PNG 文件之外 我还会also就像生成散点图中各个点的像素坐标列表一样 我用来生成散点图 PNG 文件的代码基本上是这样的 from matplotli
  • 如何将reportlab与Google应用程序引擎一起使用

    我无法在谷歌应用程序引擎下正确导入reportlab 根据以下guide http blog notdot net 2010 04 Generating PDFs on App Engine Python and introducing M
  • python csv按列转换为字典

    是否可以将 csv 文件中的数据读取到字典中 使得列的第一行是键 同一列的其余行构成列表的值 例如 我有一个 csv 文件 strings numbers colors string1 1 blue string2 2 red string
  • Windows 与 Linux 文本文件读取

    问题是 我最近从 Windows 切换到 Ubuntu 我的一些用于分析数据文件的 python 脚本给了我错误 我不确定如何正确解决 我当前仪器的数据文件输出如下 Header 有关仪器等的各种信息 Data 状态 代码 温度 字段等 0
  • SpaCy 中的自定义句子边界检测

    我正在尝试在 spaCy 中编写一个自定义句子分段器 它将整个文档作为单个句子返回 我编写了一个自定义管道组件 它使用以下代码来执行此操作here https github com explosion spaCy issues 1850 但
  • 使用Python重命名目录中的多个文件

    我正在尝试使用以下 Python 脚本重命名目录中的多个文件 import os path Users myName Desktop directory files os listdir path i 1 for file in files
  • Django - 缺少 1 个必需的位置参数:'request'

    我收到错误 get indiceComercioVarejista 缺少 1 个必需的位置参数 要求 当尝试访问 get indiceComercioVarejista 方法时 我不知道这是怎么回事 views from django ht
  • 从 Flask 中的 S3 返回 PDF

    我正在尝试在 Flask 应用程序的浏览器中返回 PDF 我使用 AWS S3 来存储文件 并使用 boto3 作为与 S3 交互的 SDK 到目前为止我的代码是 s3 boto3 resource s3 aws access key id

随机推荐

  • 截取鼠标指针的图片

    Windows下的鼠标经常会显示出不同的样子以提示当前的操作 所以对于很多程序来说截取鼠标指针当前的图片并进行分析是很有用处的 下面分析两种截取鼠标指针的图片的方法并给出一个示范程序 截取鼠标指针的图片首先要取得鼠标的句柄 然后用API函数
  • ESP32学习笔记05-串口事件方式读取数据

    串口中断方式处理数据 事件机构体 typedef struct uart event type t type lt UART event type size t size lt UART data size for UART DATA ev
  • leetcode 142.环形链表2

    leetcode 142 环形链表2 给定一个链表的头节点 head 返回链表开始入环的第一个节点 如果链表无环 则返回 null 如果链表中有某个节点 可以通过连续跟踪 next 指针再次到达 则链表中存在环 为了表示给定链表中的环 评测
  • VASP - Bader Charge Analysis

    Bader电荷分析 用于分析原子周围的电荷密度 从而得到原子价电子数 下载 Bader Charge Analysis 工具包 下载地址为 http theory cm utexas edu henkelman code bader 下载
  • C++中的friend详细解析

    https blog csdn net u012861978 article details 52095607
  • 奇偶数排序

    题目描述 给定一个整数数组 请调整数组的顺序 使得所有奇数位于数组前半部分 所有偶数位于数组后半部分 要求时间复杂度为O n 分析与解法 最容易想到的办法是从头到尾扫描这个数组 每遇到一个偶数 就把他单独取出来 然后把该偶数后面的所有数往前
  • vulnhub之vegeta

    目录 一 主机发现 二 端口扫描 四 信息收集 五 cyberchef解密 1 两道base64解密 2 save保存 3 qrcode module 4 二维码提取工具zbaring 六 大字典跑目录 七 bulma 八 音频分析软件au
  • spark-2.2.2-bin-hadoop2.7 安装

    1 上传spark 2 2 2 bin hadoop2 7 tgz 2 解压文件 tar zxvf spark 2 2 2 bin hadoop2 7 tgz C usr local 3 进入conf 下把spark env sh temp
  • 『NLP经典项目集』05:新年到,飞桨带你对对联

    基于seq2seq的对联生成 对联 是汉族传统文化之一 是写在纸 布上或刻在竹子 木头 柱子上的对偶语句 对联对仗工整 平仄协调 是一字一音的汉语独特的艺术形式 是中国传统文化瑰宝 这里 我们将根据上联 自动写下联 这是一个典型的序列到序列
  • Mysql 检查表是否存在并创建表,检查列是否存在并新增、修改、删除列

    判断表是否存在 不存在就可新增 CREATE TABLE IF NOT EXISTS example ENGINE InnoDB AUTO INCREMENT 1 DEFAULT CHARSET utf8 判断表字段是否存在 不存在就可新增
  • springboot好在哪

    springboot好在哪 欢迎观看 第一篇 欢迎观看 你好 这是本人第一次使用 新手发文 多多包涵 第一篇 以往的ssm框架整合通常有两种形式 一种是xml形式 一种是注解形式 不管是xml还是注解 基本都会有一大堆xml标签配置 其中有
  • C++学习之list的实现

    在了解学习list实现之前我们首先了解一下关于迭代器的分类 按功能分类 正向迭代器 反向迭代器 const正向迭代器 const反向迭代器 按性质分类 单向迭代器 只能 例如单链表 双向迭代器 可 也可 例如双链表 map和set 随机迭代
  • Unity3D 监控面板显示数据(Inspector)

    using System Collections using System Collections Generic using UnityEngine using UnityEngine Serialization AddComponent
  • 机器学习十大算法之四:SVM(支持向量机)

    SVM 支持向量机 支持向量机 Support Vector Machine 是一种十分常见的分类器 曾经火爆十余年 分类能力强于NN 整体实力比肩LR与RF 核心思路是通过构造分割面将数据进行分离 寻找到一个超平面使样本分成两类 并且间隔
  • IC卡和ID卡

    定义 最常用的感应卡分为ID卡和IC卡两种 IC卡全称集成电路卡 Integrated Circuit Card 又称智能卡 Smart Card 可读写 容量大 有加密功能 数据记录可靠 使用更方便 如一卡通系统 消费系统等 ID卡全称身
  • java.sql.SQLException: Statement.executeQuery() cannot issue statements that do not produce result

    java sql SQLException Statement executeQuery cannot issue statements that do not produce result sets 解决 看看自己的java代码里的 sq
  • Linux内核内存检测工具KASAN

    KASAN k z n KASAN 是 Kernel Address Sanitizer 的缩写 它是一个动态检测内存错误的工具 主要功能是检查内存越界访问和使用已释放的内存等问题 KASAN 集成在 Linux 内核中 随 Linux 内
  • 项目管理 附下载地址

    本书对现代项目管理的基本管理过程 知识模块 工具和方法等进行了全面的介绍 全书共有十二章 每部分都力求深入浅出 站在项目经理的角度 考虑其责任大于权力的现实 并结合时代特征 学习项目管理的软技能和硬技能 通过实际案例 高效的工具和模板 使读
  • 作为字典数据获取枚举值

    RequestMapping value getAmmeterType method RequestMethod GET ResponseBody ApiOperation notes 获取电表类型 value 获取电表类型 public
  • Python程序异常处理

    一 什么是异常 异常就是程序运行时发生错误的信号 在程序由于某些原因出现错误的时候 若程序没有处理它 则会抛出异常 程序也的运行也会随之终止 程序异常带来的问题 1 程序终止 无法运行下去 2 如果程序是面向客户 那么会使客户的体验感很差