三分钟教你读懂Python报错
本文作者:宁刘莹
文字编辑:余术玲
技术总编:张 邯
在使用Python写程序时,并不是每次的程序都能从头到尾顺利地运行,那么我们怎样知道是哪里出了问题呢?有一个非常基础但是有用的信息是我们应该掌握的,那就是Python报错,看懂报错可以帮助我们提高排错的效率,小编总结了新手入门时常见的报错信息和场景,熟悉这些报错信息,新手会犯的一些小错误只需要稍微改正一下便可。
In [1]: while true print("爬虫俱乐部")
得到报错信息如下:
了解了报错信息的大致结构之后,还需要知道不同类型的错误具体有什么含义,才能够对症下药地进行修改。常见的错误类型大致有以下7种,以表格形式总结在此,下文中会给出详细示例和解释帮助大家理解:
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}为奇数")
Traceback(most recent call last):
File"<ipython-input-9-3d6a2416e4f4>", line 2, in <module>
if i in even:
NameError:name 'even' is not defined
even = [2, 4,6,8,10]
就得到了以下输出结果:
1为奇数
2为偶数
3为奇数
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类型错误
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)
lista
Out[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元我们即可给您开具发票,发票类别为“咨询费”。用心做事,只为做您更贴心的小爬虫!
往期推文推荐
关于我们
微信公众号“爬虫俱乐部”分享实用的stata命令,欢迎转载、打赏。爬虫俱乐部是由李春涛教授领导下的研究生及本科生组成的大数据分析和数据挖掘团队。
此外,欢迎大家踊跃投稿,介绍一些关于stata的数据处理和分析技巧。
投稿邮箱:statatraining@163.com
投稿要求:
1)必须原创,禁止抄袭;
2)必须准确,详细,有例子,有截图;
注意事项:
1)所有投稿都会经过本公众号运营团队成员的审核,审核通过才可录用,一经录用,会在该推文里为作者署名,并有赏金分成。
2)邮件请注明投稿,邮件名称为“投稿+推文名称”。
3)应广大读者要求,现开通有偿问答服务,如果大家遇到关于stata分析数据的问题,可以在公众号中提出,只需支付少量赏金,我们会在后期的推文里给予解答。