你真的看得懂报错吗?

简介: 你真的看得懂报错吗?

看懂报错

对于不少刚学python的小白,遇到python报错后总是一头露水,不知所措。今天这篇文章就带你看懂报错信息。

我们先从一个最简单的一个例子讲起, 除法中分母不能为零

d420948ca8dae9790aee17f31045c2de_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

上面的代码1/0会报错,我们来分析一下python所给出的报错信息。

Traceback (most recent call last):
  File "/home/deng/python/error/test.py", line 1, in <module>
    a = 1 / 0
ZeroDivisionError: division by zero

可以发现,第2行中告诉了我们出错的文件,出错的行数,分别是test.py文件和第1行,紧接着第3行给出了导致报错的代码内容,第4行给出了报错的原因(报错类型)即除数为0。以上就是python中一个最简单的报错信息,基于这些信息,我们可以快速定位错误位置,并进行修改。下面来看一个稍微复杂的例子。下面的例子里面引入了几个函数,同时函数和函数之间还进行了互相调用,这样是为了模拟一个相对复杂的情况。

同样的,我们也在a函数内部设置了一个1/0的错误。

03a72c3fd00541235cb77c61f2012350_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

在分析上面的错误信息之前,首先这里需要了解一个概念,叫做调用顺序(调用栈),比如在b函数中调用了a函数,那么当运行b函数的时候,应该是b函数先运行,然后a函数再运行,这里的先后顺序就是调用栈。你可以将这种先后关系理解为洋葱,最外层的总是比最内层的先被剥掉。在python中,错误信息是按照由外而内的顺序进行输出,即先输出最先报错的地方,然后一层层定位到真正报错的地方。

明白了上面的知识,我们再来看代码和对应的报错信息。代码中c函数调用了b函数,而b函数调用了a函数,所以函数运行的顺序应该是 c > b > a,而错误位于a中,所以报错信息应该是先从c开始,到a结束。左边的报错信息中先是输出了c的报错信息,然后输出了b的报错信息,然后输出了a的报错信息,发现a是真正报错的位置,然后给出了a中报错的行数和对应报错代码。这样就定位了python中真正的错误位置,从而进行相应的修复。

在使用某些第三方的包时,代码报错可能会输出很长很长的错误,这一点是很正常的,对于一个大型的python项目,内部存在十分复杂的调用关系,所以当出现错误时,python会按照这个复杂的调用关系依次输出,其实我们可以直接来看最下面的一个报错信息,就可以定位真正的报错位置了。

学会提问

当你遇到了错误以后,实在是自己解决不了,需要向其他人请求帮助时,一套老练的提问方式十分必要。遇到了报错后,不要慌张,把你的代码和你的报错信息一并发给你请求的人,同时报错信息一定要发全(有些同学可能觉得这个报错信息太长了,只选择了报错信息的前几行,反而把最后的报错信息给遗漏了)。你会发现向别人寻求代码帮助的时候,像极了发生火灾时拨打119报警,你不能一直跟接线员嚷嚷着着火了,着火了,而是要冷静的,将火灾的位置,可能引起火灾的原因告诉对方,这样才能在最短的时间到达火场,处理险情。

常见错误

对于大多数错误,其实你的编辑器(pycharm或者vscode)都可以给出相应的提示,这里列出一些不太能给出提示的错误。

84f71b5af377372e6c232f3ee89b92d7_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

数组越界

a只有3个元素,a[4]则需要保证a中至少含有5个元素

0b4ab386e30bbd906c297c9fdb206a3e_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

脚本编码错误

有时候,由于代码中存在中文字符,通过windows记事本打开后再保存,可能文件的编码就被换成了中文编码(gb2312),而python默认是使用ASCII码来处理python文件的,这时再运行这个python文件就会报错。你可以在python文件头部加一行# -*- coding: gb2312 -*-,来指定python以gb2312的方式处理python文件,当然,我还是推荐你使用utf-8的编码来写python文件。

814805363f0b1f8ba5fba549fa53dd33_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

递归爆栈

python中递归有递归深度的限制,在平时的代码编写中应该避免递归的出现,或者修改python默认的递归深度

054dccd87260d5ca6bc95a444aa9f35c_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

修改递归深度

a73d94400b3db166318cd55649c296c2_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

使用循环改写递归

c731a86cad308e4caedde08693c62066_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

一种更常见的递归错误,两个函数之间相互调用,从而导致了爆栈

9158c7488643dc7b8e3f2d0631e1a154_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

在定义之前引用

在一个函数内部修改一个外部的全局变量时,应该声明这是一个全局变量

0a31f4bf00b29d59f162530ba4399e63_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png

解决方法

68ca387ed5283811dbdd697011ff114e_640_wx_fmt=png&wxfrom=5&wx_lazy=1&wx_co=1.png


相关文章
|
6月前
|
设计模式 算法 程序员
如何写出好的代码注释?
作为程序员,想必大家在日常开发中必写注释,而且在软件开发过程中,给代码写注释是一项至关重要的工作,也是一名合格的程序员该具备的编程素养。恰当的注释可以提高代码的可读性和可维护性,方便其他人理解熟悉和修改代码,但是不恰当或过度的注释可能会导致混乱和误导,会起到适得其反的作用。那么本文就来分享一些关于如何正确地给代码写注释的方法和指导原则,并提供一些减少注释但仍能让他人理解代码的方法。
159 3
如何写出好的代码注释?
|
6月前
|
设计模式 算法 Java
|
6月前
|
人工智能 程序员 API
代码注释对于程序员重要吗?
代码注释对于程序员重要吗?
61 0
|
数据库
我又写了一堆烂代码
“我又写了一堆烂代码!” 这句话我经常对自己说,目的是为了督促自己不断地思考所写的代码是否足够可靠。
65 0
|
程序员
笑出腹肌!有些程序员真会玩代码注释
笑出腹肌!有些程序员真会玩代码注释
92 0
笑出腹肌!有些程序员真会玩代码注释
|
编解码 前端开发 程序员
为啥只跟着视频敲代码学不好编程?
为啥只跟着视频敲代码学不好编程?
443 1
|
SQL 存储 监控
聊聊那些年遇到过的奇葩代码
无论是开发新需求还是维护旧平台,在工作的过程中我们都会接触到各种样式的代码,有时候会碰到一些优秀的代码心中不免肃然起敬,但是更多的时候我们会遇到很多奇葩代码,有的时候骂骂咧咧的吐槽一段奇葩代码后定睛一看作者,居然是几个月以前自己的写的,心中难免浮现曹操的那句名言:不可能,绝对不可能。
聊聊那些年遇到过的奇葩代码
|
存储 Java
来自三段代码的疑惑~
来自三段代码的疑惑~
115 0
|
Python
又烧脑又炫技还没什么用,在代码里面打印自身
又烧脑又炫技还没什么用,在代码里面打印自身
207 0
又烧脑又炫技还没什么用,在代码里面打印自身
|
安全 JavaScript 程序员
写好代码需要举一反三
如何让代码写的更安全高效一直是程序员的不懈追求!在解决问题的同时,简介清爽,逻辑严谨的代码会让程序员更带光环。 简书亦有简码
210 0
写好代码需要举一反三