你真的看得懂报错吗?

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

看懂报错

对于不少刚学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


相关文章
|
3月前
|
人工智能 程序员 API
代码注释对于程序员重要吗?
代码注释对于程序员重要吗?
20 0
|
4月前
|
设计模式 算法 Java
|
9月前
|
SQL 人工智能 Java
程序员:你见过哪些要命的奇葩代码?
程序员:你见过哪些要命的奇葩代码?
82 0
|
11月前
|
数据库
我又写了一堆烂代码
“我又写了一堆烂代码!” 这句话我经常对自己说,目的是为了督促自己不断地思考所写的代码是否足够可靠。
40 0
|
程序员
笑出腹肌!有些程序员真会玩代码注释
笑出腹肌!有些程序员真会玩代码注释
65 0
笑出腹肌!有些程序员真会玩代码注释
|
编解码 前端开发 程序员
为啥只跟着视频敲代码学不好编程?
为啥只跟着视频敲代码学不好编程?
308 1
|
存储 Java
来自三段代码的疑惑~
来自三段代码的疑惑~
89 0
|
开发者 Python
一日一技:8行炫技代码,知识点多得不得了
一日一技:8行炫技代码,知识点多得不得了
251 0
一日一技:8行炫技代码,知识点多得不得了
|
安全 JavaScript 程序员
写好代码需要举一反三
如何让代码写的更安全高效一直是程序员的不懈追求!在解决问题的同时,简介清爽,逻辑严谨的代码会让程序员更带光环。 简书亦有简码
172 0
写好代码需要举一反三
|
程序员
都说代码注释是程序员必备技能,但是你这注释也太奇葩了吧!
都说代码注释是程序员必备技能,但是你这注释也太奇葩了吧!
131 0
都说代码注释是程序员必备技能,但是你这注释也太奇葩了吧!