本文封面图片来源于 Jim Zhang 。
本讲义中部分内容参考自以下文章或网站:
写在前面
之所以要写这篇文章,一方面是因为我们在coding的时候经常遇到代码跑不通的情况,这还怎么让我开开心心的写bug?另外hobee在答疑的时候也经常遇到小伙伴来问为什么某一段代码会报错,可能是之前玩电脑的时候,遇到报错就像遇到‘歪比巴卜’一样傻也看不懂,就以为Python的报错也差不多,解决报错超出自己的能力范围,直接跑去问老师或助教,但其实很多情况下Python的报错信息写的都是很清楚的,最大的障碍应该是语言障碍,只要明白那行英文说的是什么东西,解决起来不是什么问题。
这篇文章将常见的Python错误类型与处理方法进行总结,可供有需要的小伙伴学习交流使用。
常见异常类型
AttributeError
AttributeError:属性错误,特性引用和赋值失败时会引发属性错误
1 | 0 a = |
出现这个异常,一种情况是调用了错误的方法,根据异常提示也可以看出,a是一个整型变量,但append是列表类型的一个方法,所以对一个整型变量使用列表的方法自然会出现问题。
解决方式就是检查报错处的内容,根据报错信息看看有没有出现调用方法的问题。
NameError
NameError:试图访问的变量名不存在
1 | b |
当我尝试访问一个没有定义过的变量的时候,程序就会抛出这个异常。
解决方法也很简单,就是在使用之前现给它初始化一下。
SyntaxError
SyntaxError:语法错误,代码形式错误
1 | if a=b: |
进行条件判断的时候使用’=’而不是’==’会导致语法错误。
1 | if a |
当使用if、while、for、class、def但末尾没有加冒号,或使用中文符号时,也会抛出该异常。
1 | print(Hello!') |
字符串少一般引号,函数调用少一半括号等等,均会抛出异常。
这种异常通常会明确指出异常位置,找到相应错误进行修改就可以了。
KeyError
KeyError:使用了映射中不存在的关键字(键)时引发的关键字错误
1 | a = {} |
由于字典a中并没有’key’这个键,所以尝试调用时会抛出KeyError
解决方法是在调用之前先将这个键加入到字典中,如果之前已经加入,检查一下是否在之后将它删除了。
IndexError
IndexError:索引错误,使用的索引不存在,常索引超出序列范围,什么是索引
1 | 10] a[ |
这种错误通常表现为数组、字符串、元组等类型的越界访问。
1 | a = [1,2,3,4] |
在上面这个情况下,看上去没问题但会抛出越界异常,是因为在循环中我们将想要遍历的数组修改了,增加元素还好,一旦删除了元素,会导致数组长度变短,如果循环次数还是原来的数组长度的话,必然会导致数组越界。这个问题一般很难发现,所以当出现越界但又不知道到底是哪里出现问题的话,可以往这个方向思考一下。
IndentationError
IndentationError:缩进错误,错误的使用缩进量。
1 | if a: |
由于Python是对缩进敏感的,同一逻辑层应该保持相同的缩进,":"
标记一个新的逻辑层, 增加缩进
进入下一个代码层,减少缩进
返回上一个代码层。如果错误使用就会抛出这个异常。
解决方法就是就错误位置增加或减少相应的缩进。
更多有关缩进的信息可以浏览这篇文章。
TypeError
TypeError:类型错误,内建操作或是函数应于在了错误类型的对象时会引发类型错误
1 | a = 'Welcome to hobees blog.' |
通常情况下,尝试对字符串进行修改将会抛出类型错误异常。众所周知,字符串是不可修改的数据类型。
一般可以通过字符串拼接的方法进行解决
1 | a = 'Welcome to hobees blog.' |
ZeroDivisonError
ZeroDivisonError:除数为0,在用除法操作时,第二个参数为0时引发了该错误
1 | 1/0 |
这个就不用多说了吧…
ValueError
ValueError:值错误,传给对象的参数类型不正确,像是给int()函数传入了字符串数据类型的参数。
1 | int('0b123') |
当给函数传入不正确的参数时,会抛出值错误异常。检查参数类型和数量,重新传入正确的即可。
不常见异常类型
不常见的异常类型太多了,通常情况下也很难遇到,我就不介绍了,欢迎有兴趣的小伙伴进行补充。
简单异常处理
try-except
try是Python中的一个保留字,具体作用是尝试执行try中的代码内容,如果try后的语句发生了异常,则跳出该段语句,执行except中的内容。
except可以捕捉到异常类型,具体用法可分为以下几类:
except:
只要try中出现异常,就会执行except中的代码。1
2
3
4
5
6
7
8a = []
try:
a[100] = 1
print(1)
except:
print(2)
2因此,只要你的代码使用了以下内容,就永远不会报错(开玩笑呢你可别当真,不报错不代表没有错误
1
2
3
4try:
code
except:
passexcept Type:
只有出现1
2
3
4
5
6
7
8
9
10
11a = []
try:
a[100] = 1
print(1)
except ValueError:
print(2)
Traceback (most recent call last):
File "C:/Users/和毕/Desktop/1.py", line 3, in <module>
a[100] = 1
IndexError: list assignment index out of rangeexcept Type as data:
获取异常信息存入data1
2
3
4
5
6
7
8
9
10
11a = []
data = ''
try:
a[100] = 1
print(1)
except IndexError as data:
print(2)
print(data)
2
list assignment index out of rangeexcept (Type1,Type2,Type3):
同时处理多种异常,捕捉到元组中任何一种异常,都会执行except中的操作。
1
2
3
4
5
6
7
8a = []
try:
a[100] = 1
print(1)
except (ValueError,IndexError):
print(2)
2except Type1:
except Type2:
分类处理异常,类似c语言中的switch-case,捕捉到不同异常进行不同的操作。1
2
3
4
5
6
7
8
9
10a = []
try:
a[100] = 1
print(1)
except ValueError:
print(2)
except IndexError:
print(3)
3
try和except应该成对出现,只有try而没有except会抛出语法错误。
千万要注意,通常情况下,try可以利用异常,但无法解决异常。虽然使用try之后不会再出现异常,但只是Python将这个异常‘藏’了起来,并没有使之解决,所以平时不建议遇到异常就使用try。
raise
这玩意我自己也没用过,如果有时间我再补充(我鸽了…具体使用可以参考本文开头出现的第三篇文章。
写在最后
以上就是常见的异常类型及其简单的解决方案,如果有遗漏的内容欢迎在评论区补充,如果有错误的内容也欢迎在评论区中指正。