15.Python 异常处理和程序调试

1. 异常处理

异常就是在程序执行过程中发生的超出预期的事件。一般情况下,当程序无法正常执行时,都会抛出异常。

  • 在开发过程中,由于疏忽或考虑不周,出现的设计错误。因此,在后期程序调试中应该根据错误信息,找到出错位置,并对错误代码进行分析和排错。
  • 难以避免的运行问题,如读写权限不一致、网络异常、文件不存在、内存溢出、数据类型不一致等。针对这类异常,在设计时可以主动捕获异常,防止程序意外终止。
  • 主动抛出异常。在程序设计中,可以根据设计需要主动抛出异常,引导程序按照预先设计的逻辑运行,防止用户不恰当地操作。

当发生异常时,一般应该捕获异常,并妥善处理。如果异常未被处理,程序将终止运行,因此为程序添加异常处理,能使程序更健壮。

异常也是一种类型,所有的异常实例都继承自BaseException基类。使用Exception可以捕获所有类型的异常。

使用try…except语句可以捕获和处理异常,语句格式如下:

try:   # 捕获异常
    <执行语句>
except [异常类型[ as 别名]]: # 处理异常
    <处理语句>

把目标代码放在try语句中,在except关键字后面设置可选的异常类型。如果省略异常类型,则表示捕获全部异常类型。如果类型的名称比较长,可以使用as关键字设置别名,方便在异常处理中引用。如果不需要处理异常,可以在except代码块中使用pass语句忽略。

try:
    '1' + 0 # 错误运算
except: # 捕获所有的异常
    print('发生错误') # 提示错误信息

try:
    f = open('test.txt','r') # 打开不存在的文件
except IOError as e:  # 捕获IOError类型异常
    print('错误编号:%s,错误信息:%s'%(e.errno,e.strerror)) #显示错误信息

try:
    f = open('test.txt','r') # 打开不存在的文件
except Exception as e:  # 捕获IOError类型异常
    print('错误编号:%s,错误信息:%s'%(e.errno,e.strerror)) #显示错误信息

使用except语句可以同时处理多个异常,语法格式如下:

# 多个异常类型以元组形式进行设置,当try代码发生其中一个,都被except处理。
try: # 捕获异常
    <执行语句>
except ([Exception1[,Exception2,...,ExceptionN]]) [ as 别名]: # 处理异常
    <处理语句>

# 多个异常类型按优先顺序分别进行处理
try: # 捕获异常
    <执行语句>
except ([Exception1[,Exception2]]) [ as 别名]:
    <处理语句1>
...
except [Exception]:
    <处理语句N>

# 样例
li = [] # 定义空列表
try:
    print(c) # 发生NameError异常
    print(3/0) # 发生ZeroDivisionError异常
    li[2] # 发生IndexError异常
    a = 123 + 'hello world'  # 发生TypeError异常
except NameError as e:
    print('出现NameError异常!',e)
except ZeroDivisionError as e:
    print('出现ZeroDivisionError异常!',e)
except IndexError as e:
    print('出现IndexError异常!',e)
except TypeError as e:
    print('出现TypeError异常!',e)
except Exception as e:
    print('出现其它异常!',e)

try代码块中可以嵌套使用try…except结构,设计多层嵌套的异常处理结构,异常对象可以从内向外逐层向上传递。

try:
    try:
        try:
            f = open('test.txt','r') # 打开并不存在的文件
        except NameError as e: # 捕获未声明的变量异常
            print('NameError')
    except IndexError as e: # 捕获索引超出异常
        print('IndexError')
except IOError as e: # 获取输入或输出的异常
    print('IOError')

# 输出:IOError

try…except异常处理结构允许附带一个可选的else子句,用来设计当没有发生异常时,正常处理的代码块。else子句在异常发生时,不会被执行,只有当异常没有发生时才会执行。

try: # 捕获异常
    <执行语句>
except [异常类型][ as 别名]: # 处理异常
    <异常处理语句>
else: # 当异常未发生时执行
    <正常处理语句>

try:
    f = open('test.txt','r') # 打开文件
except:  # 如文件打开异常,则执行此
    print('出错了')
else: # 如文件正常打开,则执行此
    print(f.read()) # 读取文件内容

try:
    f = open('test.txt','r') # 打开文件
    print(f.read()) # 如文件打开异常,则不执行此
except: # 如文件打开异常,则执行此
    print('出错了')

善后处理try…except异常处理结构还可以带一个可选的finally子句,它表示无论异常是否发生,最后都要执行finally语句块。

try: # 捕获异常
    <执行语句>
except [异常类型][ as 别名]: # 处理异常
     <异常处理语句>
else: # 当异常未发生时执行
    <正常处理语句>
finally: # 不管异常是否发生,最后都要执行
    <最后必须处理语句>

import time 
i = 1 
while True: # 无限循环
    try:
        print(i) # 打印变量
        continue # 退出执行下一次循环
        print('永不执行') # 不执行该句
    finally: 
        time.sleep(1) # 暂停1s
        i += 1 # 递增变量
        continue # 退出执行下一次循环
        print('永不执行') # 不执行语句

抛出异常:使用raise语句主动抛出一个异常,这样可以确保程序根据开发人员的设计逻辑执行,也可以对用户的行为进行监控,避免意外操作。

raise [Exception[(args[,traceback])]]

raise 语句3种用法:

  • raise:单独一个raise。该语句将引发当前上下文捕获的异常,默认引发RuntimeError异常。
  • raise 异常类名称:raise 后带一个异常类名称,表示引发执行指定类型的异常。
  • raise 异常类名称(描述信息):在引发指定类型的异常时,显示异常的描述信息。
try:
    a = input('输入一个数')
    if (not a.isdigit()):
        raise
except RuntimeError as e:
    print('引发异常:',repr(e)) # 引发异常: RuntimeError('No active exception to reraise')

def test(num):
    try:
        if type(num) != int: # 如果为非数字的值,则抛出TypeError错误
            raise TypeError('参数不是数字') 
        if num <= 0: # 如果为非正整数,则抛出ValueError错误
            raise ValueError('参数为不大于0的整数')
        print(num) # 打印数字
    except Exception as e:
        print(e) # 打印错误信息
test('1') # 参数不是数字
test(0) # 参数为不大于0的整数
test(2) # 2

自定义异常:自定义异常类型必须直接或间接继承Exception类。

class MyError(Exception):
    def __init__(self,msg):
        self.msg=msg
    def __str__(self):
        return self.msg
try:
    raise MyError('自定义错误信息') # 主动抛出自定义错误
except MyError as e:
    print(e) # 打印:自定义错误信息

跟踪异常:使用traceback可以跟踪异常,记录异常发生时有关函数调用的堆栈信息。具体格式如下:

import traceback
try:
    1/0
except Exception as e:
    traceback.print_exc() # 打印详细的错误信息
    traceback.format_exc() # 格式化字符串的形式返回错误信息
    # 把错误信息直接保存到外部文件中
    traceback.print_exc(file=open('log.log',mode='a',encoding='utf-8'))

2. 程序调试

在编写程序中,常见错误有两种:语法错误和异常。语法错误又称解析错误,SyntaxError: invalid syntax 。

在这里插入图片描述

即使语句或表达式在语法上是正确的,但在执行时也可能会引发错误,该错误称为异常,异常如果不被捕获,被程序处理,则会中止程序,并显示异常提示信息。

在这里插入图片描述

使用assert语句可以定义断言,断言用于判断一个表达式,在表达式条件为Flase的时候触发异常,而不必等待程序运行后出现崩溃的情况。

def foo(s):
    n = int(s)
    assert n != 0,'n is zero!' # 设置断言
    return 10/n
def main():
    foo('0')

main()

# 在交互式模式中,可以使用-O参数关闭 assert
python -O test1.py

使用pdb,pdb 是Python自带的一个包,提供了一种交互的源代码调试功能,主要特性包括:设置断点、单步调试、进入函数调试、查看当前代码、查看栈片段、动态改变变量的值等。pdb常用的调试命令:

  • break或b:设置断点。
  • continue或c:继续执行程序。
  • list或l:查看当前行的代码段。
  • step或s:进入函数。
  • return或r:执行代码直到从当前函数返回。
  • exit或q:中止并退出。
  • next或n:执行下一行。
  • p val:打印变量的值。
  • help:帮助。
# 新建test1.py文件,代码如下
s = '0'
n = int(s)
print(10/n)
# cd 命令进入到test1.py文件所在目录
cd edition_master
# 启动pdb调试器
python -m pdb test1.py
# 执行操作
l # 查看当前行的代码段
n # 下一步
p s # 打印变量s
q # 退出

当程序代码较多时,在可能出错的地方插入pdb.set_trace(),则不需要单步执行。

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

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

相关文章

Vector - CANoe - Vector Hardware Manager以太网

前面的文章中有介绍过基于Network based mode和channel base mode的环境配置&#xff0c;不过我们都是使用比较旧的办法&#xff0c;在我使用了一段时间Vector Hardware Manager配置之后发现这个更加好用结合之前的配置方法&#xff0c;使用起来也更加的灵活&#xff0c;今天就…

Linux系统介绍及文件类型和权限

终端:CtrlAltT 或者桌面/文件夹右键,打开终端 切换为管理员:sudo su 退出:exit 查看内核版本号:uname -a 内核版本号含义:5 代表主版本号;13代表次版本号;0代表修订版本号;30代表修订版本的第几次微调;数字越大表示内核越新. 目录结构 /bin:存放常用命令(即二进制可执行程序…

Redis打包事务,分批提交

一、需求背景 接手一个老项目&#xff0c;在项目启动的时候&#xff0c;需要将xxx省整个省的所有区域数据数据、以及系统字典配置逐条保存在Redis缓存里面&#xff0c;这样查询的时候会更快; 区域数据字典数据一共大概20000多条,&#xff0c;前同事直接使用 list.forEach…

视频如何去水印?怎么下载保存无水印视频?

在社交媒体平台上&#xff0c;如某音、某手等&#xff0c;你是否曾经在观看视频时&#xff0c;因为烦人的水印而感到烦恼&#xff1f;是否曾经因为水印遮挡了关键信息&#xff0c;而错过了重要的内容&#xff1f;今天&#xff0c;我要向大家介绍三种视频去水印的方法&#xff0…

怎样通过代理ip提高上网速度

在当今互联网高度发达的时代&#xff0c;我们经常需要使用代理IP来隐藏自己的真实IP地址或提高网络连接速度。然而&#xff0c;有些用户可能会遇到代理IP无法提高网络速度的情况。那么&#xff0c;如何通过代理IP提高上网速度呢&#xff1f;以下是几个技巧&#xff1a; 1.选择…

【性能优化】CPU利用率飙高与内存飙高问题

&#x1f4eb;作者简介&#xff1a;小明java问道之路&#xff0c;2022年度博客之星全国TOP3&#xff0c;专注于后端、中间件、计算机底层、架构设计演进与稳定性建设优化&#xff0c;文章内容兼具广度、深度、大厂技术方案&#xff0c;对待技术喜欢推理加验证&#xff0c;就职于…

Redis入门教程

1. 什么是NoSql NoSQL一词最早出现于1998年&#xff0c;是Carlo Strozzi开发的一个轻量、开源、不提供SQL功能的关系数据库。2009年&#xff0c;Last.fm的Johan Oskarsson发起了一次关于分布式开源数据库的讨论&#xff0c;来自Rackspace的Eric Evans再次提出了NoSQL的概念&am…

在数组的指定位置插入指定元素值numpy.insert()

【小白从小学Python、C、Java】 【计算机等级考试500强双证书】 【Python-数据分析】 在数组的指定位置插入指定元素值 numpy.insert() [太阳]选择题 请问以下代码中最后输出结果是&#xff1f; import numpy as np arr np.array([1, 2, 3]) print("【显示】arr ",…

C/C++内存管理(2):`new`和`delete`的实现原理

new和delete操作自定义类型 class Stack { public:Stack(int capacity 3):_top(0), _capacity(capacity){cout << "Stack(int capacity 3)" << endl;_a new int[capacity];}~Stack(){cout << "~Stack()" << endl;delete _a;_to…

LeetCode | 622. 设计循环队列

LeetCode | 622. 设计循环队列 OJ链接 思路&#xff1a; 我们这里有一个思路&#xff1a; 插入数据&#xff0c;bank往后走 删除数据&#xff0c;front往前走 再插入数据&#xff0c;就循环了 那上面这个方法可行吗&#xff1f; 怎么判断满&#xff0c;怎么判断空&#xff1…

XDR 网络安全:技术和最佳实践

扩展检测和响应&#xff08;XDR&#xff09;是一种安全方法&#xff0c;它将多种保护工具集成到一个统一的集成解决方案中。它为组织提供了跨网络、端点、云工作负载和用户的广泛可见性&#xff0c;从而实现更快的威胁检测和响应。 XDR的目标是提高威胁检测的速度和准确性&…

Python 如何开发出RESTful Web接口,DRF框架助力灵活实现!

Django Rest Framework&#xff08;DRF&#xff09;是构建强大且灵活的Web API的优秀工具。它基于Django&#xff0c;提供了一套用于构建Web API的组件和工具&#xff0c;简化了API开发过程&#xff0c;同时保留了Django的优雅和强大。 一、Web应用模式 在开发Web应用时&…

2023年第十六届中国系统架构师大会(SACC2023)-核心PPT资料下载

一、峰会简介 本届大会以“数字转型 架构演进”为主题&#xff0c; 涵盖多个热门领域&#xff0c;如多云多活、海量分布式存储、容器、云成本、AIGC大数据等&#xff0c;同时还关注系统架构在各个行业中的应用&#xff0c;如金融、制造业、互联网、教育等。 与往届相比&#…

新王加冕,GPT-4V 屠榜视觉问答

当前&#xff0c;多模态大型模型&#xff08;Multi-modal Large Language Model, MLLM&#xff09;在视觉问答&#xff08;VQA&#xff09;领域展现了卓越的能力。然而&#xff0c;真正的挑战在于知识密集型 VQA 任务&#xff0c;这要求不仅要识别视觉元素&#xff0c;还需要结…

Python中match-case语法: 引领新的模式匹配时代

更多Python学习内容&#xff1a;ipengtao.com Python在其最新的版本中引入了match-case语法&#xff0c;这是一项强大的功能&#xff0c;为开发者提供了更加灵活和直观的模式匹配方式。本文将深入探讨match-case的各个方面&#xff0c;并通过丰富的示例代码&#xff0c;帮助大家…

IDEA、PHPSTORM 在命令行中进行 PHP debug

然在终端执行控制器的方法php yii test/ab 即可看到触发debug 调试

手写工作流设计模式,针对常见的工作流步骤流转,减少过多的if/else,提升编程思维

需求 这一年下来&#xff0c;写两次工作流流转&#xff0c;总结下经验。 第一次写的时候&#xff0c;只找到用模版设计模式包裹一下&#xff0c;每个方法都做隔离&#xff0c;但是在具体分支实现的时候&#xff0c;if/else 满屏分&#xff0c;而且因为要针对不同情况&#xff…

通过云服务器部署JavaWeb项目

文章目录 搭建Java运行环境部署项目更改部分项目代码打包项目把war包上传到webapps目录下验证程序 搭建Java运行环境 搭建环境的部分比较复杂&#xff0c;为了让大家的思路更加清晰特别总结为一篇博客点击查看 部署项目 更改部分项目代码 打包项目 把war包上传到webapps目录…

SpringBoot + 通义千问 + 自定义React组件,支持EventStream数据解析!

一、前言 大家好&#xff01;我是sum墨&#xff0c;一个一线的底层码农&#xff0c;平时喜欢研究和思考一些技术相关的问题并整理成文&#xff0c;限于本人水平&#xff0c;如果文章和代码有表述不当之处&#xff0c;还请不吝赐教。 最近ChatGPT非常受欢迎&#xff0c;尤其是…

链表的回文结构

题目描述 题目链接&#xff1a;链表的回文结构_牛客题霸_牛客网 (nowcoder.com) 题目分析 我们的思路是&#xff1a; 找到中间结点逆置后半段比对 我们可以简单画个图来表示一下&#xff1a; ‘ 奇数和偶数都是可以的 找中间结点 我们可以用快慢指针来找中&#xff1a;l…