查看原文
其他

三分钟教你读懂Python报错

爬虫俱乐部 Stata and Python数据分析 2022-03-15

本文作者:宁刘莹

文字编辑:余术玲

技术总编:张   邯 

重磅!!!爬虫俱乐部将于2019年10月2日至10月5日在湖北武汉举行Python编程技术培训,本次培训采用理论与案例相结合的方式,旨在帮助零基础学员轻松入门Python,由浅入深学习和掌握Python编程技术,尤其是爬虫技术和文本分析技术。该培训目前在火热招生中,点击《爬虫俱乐部2019十一Python编程技术培训报名啦!》或点击文末阅读原文,了解培训详细信息,抓紧时间报名吧!

在使用Python写程序时,并不是每次的程序都能从头到尾顺利地运行,那么我们怎样知道是哪里出了问题呢?有一个非常基础但是有用的信息是我们应该掌握的,那就是Python报错,看懂报错可以帮助我们提高排错的效率,小编总结了新手入门时常见的报错信息和场景,熟悉这些报错信息,新手会犯的一些小错误只需要稍微改正一下便可。


一、报错信息的结构
错误是指一个在程序执行过程中发生,并影响程序正常运行的事件。当Python脚本出现异常时,如果不做任何处理,那么程序就会终止运行。通常情况下,报错的信息分为两部分:第一部分显示了出错的文件位置并标注了具体出错的位置,以堆栈回溯的形式显示发生异常时的上下文,第二部分标注了错误类型及对该错误的大致解释。
举个例子,假设我们想要输出“爬虫俱乐部”这几个字:
In [1]: while true print("爬虫俱乐部")

得到报错信息如下:

从报错系统给出的反馈看,错误出现在第一行(line 1),程序下面向上的小箭头“^”指明了该行程序第一次出现错误的位置,最后一行报错信息标注了出错类型为语法错误(SyntaxError),并给出了详细的解释是非法语法(invalid syntax)。稍想一下,我们可以发现,条件语句后面少了冒号,导致语法错误。

二、错误类型

了解了报错信息的大致结构之后,还需要知道不同类型的错误具体有什么含义,才能够对症下药地进行修改。常见的错误类型大致有以下7种,以表格形式总结在此,下文中会给出详细示例和解释帮助大家理解:

1. SyntaxError语法错误
以这样一段简单的程序为例:
In [2]: print(helloworld) 
File"<ipython-input-1-6135c6da936c>", line 1 print(hello world) ^SyntaxError: invalid syntax

这里提示语法错误的原因是,如果要print出一串字符,需要加引号,基于此,我们修改这段程序,再次运行:

In [3]: print("helloworld")hello world

字符串被成功输出了。


2. NameError变量名错误

出现变量名错误常常是由于在程序中使用了前文没有定义的变量名,举例如下。
In[4]: for i in range(1,4):   ...:    if i in even:   ...:        print(f"{i}为偶数")   ...:    else: ...: print(f"{i}为奇数")
这是一个小的循环,目的是判断整数1到3这三个自然数是否在偶数集“even”中,如果在“even”中,就输出“i为偶数”,否则就输出“i为奇数”。这段程序运行后出现了以下报错信息:
Traceback(most recent call last):
File"<ipython-input-9-3d6a2416e4f4>", line 2, in <module>    if i in even:    NameError:name 'even' is not defined
此时报错类型为NameError,具体原因是“even”是一个没有被定义的名称,也就是说在进行判断之前首先要定义“even”,在循环之前加入语句:
even = [2, 4,6,8,10]

就得到了以下输出结果:

1为奇数2为偶数3为奇数

3. IndentationError代码缩进错误
代码缩进错误是一种在写循环时容易发生的错误,尤其是在写两层及两层以上的循环时。举个例子,假设要从1-3三个自然数里分辨出每个数字是否是质数,如果是,输出“n是质数”,如果不是,则输出“n不是质数”。特别地,输出“1既不是质数,也不是合数”,那么我们就应首先将n为1和n不为1分为两种情况,再对n不为1的所有数字进行判断。判断质数的方式为:用n除以除了1和它本身之外的所有数字(即2-n),如果都无法整除,则该数字为质数。初步写出程序如下:
In [5]: for n in range(1, 4):   ...:     if n == 1:   ...:         print("1既不是质数,也不是合数")   ...:     else:   ...:         for i in range(2, n):   ...:             if n%i == 0:   ...:             print(f"{n}不是质数")   ...:                   break   ...:             else: ...: print(f"{n}是质数")

发生报错信息如下:

File"<ipython-input-5-31fae9dd7b3d>", line 7    print(f"{n}不是质数")        ^IndentationError: expected an indented block

我们得到反馈信息,提示错误类型为缩进错误,出错误位置是第7行,这里应该有一个缩进。即如果想要把符合if后面条件的语句打印出来,就要在print和break两行命令之前再多加一个缩进,于是我们修改之后程序如下:

In [6]: for n in range(1, 4): ...: if n == 1: ...: print("1既不是质数,也不是合数") ...: else: ...: for i in range(2, n): ...: if n%i == 0: ...: print(f"{n}不是质数") ...: break ...: else: ...: print(f"{n}是质数")

此时得到结果如下:

1既不是质数,也不是合数2是质数3是质数

输出的结果符合我们的预期目标。


4. TypeError类型错误

继续沿用“代码缩进错误”中的例子,仅仅把第二个和第三个print()里的内容换掉:
In [7]: for n in range(1, 4): ...: if n == 1: ...: print("1既不是质数,也不是合数") ...: else: ...: for i in range(2, n): ...: if n%i == 0: ...: print(n + "不是质数") ...: break ...: else: ...: print(n + "是质数")

运行程序后,第一个print()里的内容被成功输出,并且紧跟着出现了报错信息:

1既不是质数,也不是合数---------------------------------------------------------------------------TypeError Traceback (most recent call last)<ipython-input-9-96c8609088c4> in <module>() 8 break 9 else:---> 10 print(n +"是质数") TypeError: unsupported operand type(s) for +: 'int' and 'str'

报错系统提示出现了类型错误,这是因为数字类型不能与字符类型直接相加,如果目的是输出一句字符文字,可以使用f-string的方法,该方法具体在往期推文《格式化字符串方法的比较》中详细介绍过。这段程序的正确写法见上一小节中的第二段程序。


5.  AttributeError对象属性错误

依然以一个例子解释:

In [8]: stra="abcdefg"stra.append("hijk")print(stra)

得到的报错信息如下:

AttributeError Traceback (most recent call last)<ipython-input-2-eaee19f84344> in <module> 1stra="abcdefg"----> 2 stra.append("hijk")AttributeError: 'str' object has no attribute 'append'

这里出现对象属性错误是因为,字符串没有append方法,根据报错的类型,我们进行修改如下:

In [9]: lista=[1234567]lista.append(89)listaOut[9]: [1234567, 89]

这样程序就能顺利运行了。


6.  KeyError字典键值错误

我们知道字典由若干键值对构成,并且可以通过输入键来输出对应的值,但如果输入的键不存在,就会发生报错。例如字典a共有5对键值对,其中第5个键对应的值是一个字典:

In [10]: dicta = {'A':1, 'B':2, 'C':3, 'D':4, 'E':{1:'a', 2:'b', 3:'c',4:'d'}}dicta['B']Out[10]: 2

此时想访问“E”对应的字典中键为“2”对应的值“b”:

In [11]: dicta[2]Traceback (most recent call last): File"<ipython-input-52-8274e09a602e>", line 1, in <module>    dicta[2]KeyError: 2

由报错信息可以看出,在想要输出键“2”对应的值时出现了字典键值错误,这里是因为“b”是dicta中“E”对应的字典中的值而不是dicta的,因此修改程序如下:

In [12]: dicta['E'][2]Out[12]: 'b'

这样就能正确输出了。


7.  IndexError索引值错误

In [13]: lista = [1,2,3,4,5]lista[5]---------------------------------------------------------------------------IndexError Traceback (most recent call last)<ipython-input-2-4d7588fcff97> in <module>()----> 1 lista[5] IndexError: list index out of range

错误类型为索引值错误,原因是列表索引值超出范围。

这里的索引值错误原因是因为列表只有5个元素,而我们往期的推文数据类型介绍——tuple、list和range对象里也介绍过,列表中第一个元素的索引值为0,那么这里我们想要输出的最后一个元素索引值应为4或者-1,lista里不存在索引值为5的元素,因此报错。

拥有了读报错信息的能力,将会对于处于摸索期的Python新手带来很大的帮助。当然,有时报错信息不能给与我们足够的信息,这时需要采用各种方法调试程序,如我们爬虫俱乐部往期推文对抗bug方法介绍——爆款pysnooper你用了吗?(上篇)》对抗bug方法介绍——爆款pysnooper你用了吗?(下篇)》中介绍过的pysnooper等,后期我们会进一步介绍更多进阶调试方法,敬请期待!


对爬虫俱乐部的推文累计打赏超过1000元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!

往期推文推荐

        解析XML文件    

        命令更新之 reg2docx:将回归结果输出到word

命令更新之t2docx——报告分组均值t检验

爬虫俱乐部2019十一Python编程技术培训报名啦!

数据类型——Dict、Set与Frozenset简析 

数据类型介绍——tuple、list和range对象

把pdf文件批量转成docx文件

格式化字符串方法的比较

        朝花夕拾—— 如何输出内存中的矩阵与绘图

        Stata16新功能——定义图形元素的绝对大小

        将数值型计算“一网打尽”——(1)

        Stata16新功能之“框架”——读入多个数据集(1)

       手持Python,斗图不输!

   

关于我们

微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。


此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。

投稿邮箱:statatraining@163.com

投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。

您可能也对以下帖子感兴趣

文章有问题?点此查看未经处理的缓存