2.你是来找茬的吧?
*2.1 bug 与 debug
注:本小节带 *,不需要进行学习,可以简单进行了解
⛲️ 所谓 bug 其实有一个有趣的小故事:有一天,计算机程序之母Grace Hopper正在用马克二号调试程序,但程序却一直出现错误,所以她开始了层层排查,拆开了继电器之后她发现有一只飞蛾夹在了触点之间,卡住了机器的运行,她把虫子的尸体拿出来之后,把它粘到了自己的工作日记上,并喊它为bug(臭虫),从此 bug 化身计算机领域故障的代言词,而 debug 的意思就是为程序排除错误.
2.2 bug 的常见错误类型
2.2.1 粗心导致的错误
🚩粗心导致的错误其实是最不应该犯的错误,如果你有很多的粗心错误,那么证明,你对于 Python 的语法还不是十分的熟练,还需要继续刷题如果你把本博客中 Python程序设计训练场 的题目已经全部自己手动打过一遍了,是绝对不会再犯这种的错误的,在这里,我也总结了一些粗心的错误,大家要牢记以下几点:
1.漏了末尾的冒号,如if语句,循环语句,else子句,自定义函数等
2.缩进错误,该缩进的没缩进,不该缩进的瞎缩进
3.把英文符号写成中文符号,比如说:引号,冒号,括号
4.字符串拼接的时候,把字符串和数字拼在一起
5.没有定义变量,比如说while的循环条件的变量
6.“==”比较运算符和”=”赋值运算符的混用
2.2.2 知识点掌握不熟练导致的错误
🚩这个错误究其根本其实是和 1.2.1 粗心导致的错误 是一个属性的,比如可能会犯的列表索引越界的错误,亦或者是使用一些函数时的错误,这都是我们不熟练才导致的错误,这些错误是低级的,且是最容易更改的,唯一的办法就是:练练练!,这里强烈建议大家要刷完本博客中 Python程序设计训练场 的题目,这些题目都是博主精挑细选出来的,并且所有的题目都支持线上提交的功能。
2.2.3 思路不清导致的错误
🚩思路不清晰的错误可以说是最复杂的一个错误了,导致这个错误的原因可能有很多,拿面向过程来说,你的代码很可能会提示出现超时,亦或者是出现段错误,在竞赛中调试代码有一个很强大的操作:print 大法,即我们把我们过程中改变的量全部输出一下,尤其是例如列表,字典这种数据结构,我们输出一下它们的值,看一下是否符合预期要求,不符合的话就可以进行更改;还有一个强大的操作那就是注释大法,这个操作我们在超时和段错误的时候尤其使用,注释掉一大段内容,查看是否代码仍然超时或显示段错误,如果没有显示,那么证明,错误的代码就是你注释掉的代码,这种方法可以帮我们缩减代码的调试范围。
2.2.4 被动掉坑导致的错误
🚩这个错误其实在绝大多数情况下是没有任何问题的,它大多来源于一些奇人的神奇操作,但这不可否认是我们代码的鲁棒性较差,即代码不够健壮,举个例子,比如我们要求用户输入自己的年龄,99.9%的用户都会正常的输入自己的年龄,但总不免排除那么一两个奇葩输入自己的名字或者其他字符,这般操作后,和我们的期初要求显然是不符合的,程序自然会崩溃,亦或者是计算两个数相除,我们知道除数不可为0,大多数人用计算器也不会进行 1/0 等等这类操作,但是也总不乏有人真的输入了 1/0 这样的案例,这同样会导致我们的程序崩溃,针对以上的现象,在 Python 中提供了异常处理机制,可以在异常出现的时候立即补货,然后在内部进行“消化”,从而使得程序正常运行。代码语法结构为:
try: 可能异常的代码1 可能异常的代码2 ...... except 异常类型: 异常处理代码1(报错后执行的代码) 异常处理代码2(报错后执行的代码) ......
我们就拿除数不得为0来写一个代码:
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 21:17 # 欢迎大家关注AIoT相关博客~ try: a = int(input('请输入被除数:')) b = int(input('请输出除数:')) print(a / b) except ZeroDivisionError: print('对不起,除数不得为0') print('程序结束')
当然啦,我们说过,奇葩到处有,代码中特别多,我们从上述代码处理后其实就可以避免输入除数等于0这种异常,但是会不会有人让你输入数字,他却偏偏输入字母呢?可能没有,但作为程序员的我们这些细节必须考虑到,为此,你会发现,可能有多个不同的异常,这个时候就需要多个 except 结构,这里出现了多个异常,我们对于异常的处理顺序有这样的规定:捕获异常的顺序按照先子类后父类的顺序,为了避免遗漏可能出现的异常,可以在最后加 BaseException,表示对其他所有的异常都进行一个捕获,这里你还不了解什么是子类和父类,这个我们会在后续中进行讲解,这里你只需要知道,捕获异常的顺序是和我们解决问题的顺序是一致的,都是先解决小问题,再解决大问题,其语法结构如下:
try: 可能异常的代码1 可能异常的代码2 ...... except 异常类型1: 异常处理代码1(报错后执行的代码) 异常处理代码2(报错后执行的代码) ...... except 异常类型2: 异常处理代码1(报错后执行的代码) 异常处理代码2(报错后执行的代码) ...... ...... except BaseException: 异常处理代码1(报错后执行的代码) 异常处理代码2(报错后执行的代码) ......
更改后我们的除法程序:
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 21:17 # 欢迎大家关注AIoT相关博客~ try: a = int(input('请输入被除数:')) b = int(input('请输出除数:')) print(a / b) except ZeroDivisionError: print('对不起,除数不得为0') except ValueError: print('请输入数字') print('程序结束')
2.3 try…except…else结构
🚩如果try块中没有抛出异常,则执行else块,如果try中抛出异常,则执行except块,我们更改上述代码:
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 21:17 # 欢迎大家关注AIoT相关博客~ try: a = int(input('请输入被除数:')) b = int(input('请输出除数:')) print(a / b) # 代表捕获所有错误,并把错误原因放入e except BaseException as e: print('出错了,出现的错误为:', e) else: print('程序完好,结果为:', a / b)
2.4 try…except…else…finally结构
🚩finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源,比如我们后续学习文件处理的时候文件的关闭的东西以及数据库的连接的内容都会放在 finally 当中,这段代码是无论是否产生异常都会执行的一段代码,流程图如下图所示:
对上述代码再次进行修改:
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 21:17 # 欢迎大家关注AIoT相关博客~ try: a = int(input('请输入被除数:')) b = int(input('请输出除数:')) print(a / b) # 代表捕获所有错误,并把错误原因放入e except BaseException as e: print('出错了,出现的错误为:', e) else: print('程序完好,结果为:', a / b) finally: print('谢谢您的使用')
2.5 Python中常见的异常类型
🚩下表是 Python 中常见的异常类型,注意,Python 中的异常类型有很多,我们需要在后续的代码生涯中不断的总结:
异常类型 | 描述 |
ZeroDivisionError | 除(或取模)0 |
IndexError | 序列中没有此索引(index) |
KeyError | 映射中没有这个键 |
NameError | 未声明/初始化对象(没有属性) |
SyntaxError | Python 语法错误 |
ValueError | 传入无效的参数 |
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 21:53 # 欢迎大家关注AIoT相关博客~ # (1)ZeroDivisionError: # print(10/0) # (2)IndexError: ''' l = [1, 2, 3, 4] print(l[4]) ''' # (3)KeyError ''' d = {'name':'辰chen', 'age': 19} print(d['location']) ''' # (4)NameError # print(res) # (5)SyntaxError # int age = 19 # (6)ValueError # age = int('辰chen')
2.6 traceback模块
🚩我们使用traceback模块打印异常信息,使用 traceback 模块之前需要先导包:import traceback,使用 traceback 模块是因为,我们处理的这些异常细节,有可能在后续被存入到文件当中,去放到我们的日志文件里,所以我们会使用 traceback 模块将异常信息存储到文件里,我们把这种文件叫做 log 日志。
# 博主:辰chen # 博客地址:https://chen-ac.blog.csdn.net/ # 开发时间:2021/12/19 22:20 # 欢迎大家关注AIoT相关博客~ import traceback try: print('--------------') print(1 / 0) except: traceback.print_exc()
2.7 Python的程序调试
🚩程序的调试是我们程序员必备的本领,接下来我们来讲解如何使用 PyCharm 调试 Python 代码
1️⃣ 断点,程序运行到断点处,会暂时挂起,停止执行。此时可以详细观察程序的运行情况,方便做出进一步的判断:
我们在程序的蓝色区域可以设置断点,只需要鼠标左键点击即可,那个红色的点就是所谓的断点,再次点击这个红色的点就会取消断点
2️⃣ 进入调试视图
进入调试视图的三种方式
(1)单击工具栏上的按钮
(2)右键单击编辑区:点击:debug’模块名’
(3)快捷键:shift+F9