错误类型汇总表格

编号 错误类型 描述
A syntaxError 语法错误(情况复杂,见下)
B TypeError 类型错误(数据类型不同导致)
C NameError 名称错误(变量未声明就使用)
D ValueError 值异常(不匹配的数据类型被一起操作)
E IndentationError 缩进错误(缺少、丢失、数量不对的格式缩进)
F IndexError 偏移量错误(获取列表等类型数据的元素时偏移量设置不对)
G UnboundLocalError 作用域错误(局部变量在局部作用域内有定义,但是却在定义前使用)
H AttributeError 属性错误(某个类调用自己没有的某属性时就会报错)
I UnicodeDecodeError 解码错误(要解码的内容得跟编码时用的编码表不一致就会报错)
J FileNotFoundError 文件找不到错误(读取文件时找不到文件就会报错)

A、语法错误:

1、syntaxError:invalid syntax

无效的语法

  1. print(2019小石头)
  2. # print(2019小石头)
  3. # ^
  4. # SyntaxError: invalid syntax

2、syntaxError:invalid character in identifier

标识符中有无效的字符

  1. print(‘我左边的引号是中文的符号')
  2. # print(‘我左边的引号是中文的符号')
  3. # ^
  4. # SyntaxError: invalid character in identifier

出错场景:

这通常是因为在 python 中用了中文符号造成的。

在 Python 中,默认所有正确的语法,包括标点符号都是【英文】。不小心用了中文标点的话,计算机会无法识别,然后报错。

下边也是这种情况

3、SyntaxError: EOL while scanning string literal

扫描字符串文字终止

  1. print('我右边的引号是中文的符号‘)
  2. # print('我右边的引号是中文的符号‘)
  3. # ^
  4. # SyntaxError: EOL while scanning string literal

4、SyntaxError: 'return' outside function

return没有在function函数内使用导致的报错

  1. for i in range(5):
  2. if(i == 3):
  3. return
  4. # 报错内容如下:
  5. # return
  6. # ^
  7. # SyntaxError: 'return' outside function

B、类型错误(数据类型不同导致):

类型错误,说明是该数据类型做了不适合他自己做的事情。

1、TypeError: unsupported operand type(s) for ...

出错场景:

不同类型的数据进行结合计算或处理,就会发生错误。

  1. a = 1
  2. b = '1'
  3. print(a + b)
  4. # Traceback (most recent call last):
  5. # print(a + b)
  6. # TypeError: unsupported operand type(s) for +: 'int' and 'str'

Python 是强类型语言,不同类型的数据之间需要进行类型转换才能一起“共事”。

比如,1+'1'这么写,在 js 中肯定没问题,因为会进行类型转换,把数字 1 变成字符串 1,然后就变成了字符串拼接,最后的到 11。

但是 python 不会进行隐式类型转换,他发现你用数字 1+字符串 1,就会报类型错误,也就是 syntaxError:invalid syntax,告诉你这么写是无效的。

改正:

  1. a = 1
  2. b = '1'
  3. # print(a + b)
  4. # # 这么写报错。改正如下:
  5. print(a + int(b))
  6. # 2,将字符串转换为int类型,进行加法运算
  7. print(str(a) + b)
  8. # 11,将整数转为字符串类型,进行字符串拼接。

2、TypeError: 'bool' object is not iterable

出错场景:

当你遍历一个不能被for迭代的对象时,就会触发对应的错误。

int类型的整数对象不是可迭代的:

  1. numberValue = 2020
  2. for num in numberValue:
  3. print(num)
  4. # for num in numberValue:
  5. # TypeError: 'int' object is not iterable

float类型的浮点数对象不是可迭代的:

  1. floatValue = 1.23
  2. for num in floatValue:
  3. print(num)
  4. # for num in floatValue:
  5. # TypeError: 'float' object is not iterable

布尔类型的布尔对象不是可迭代的:

  1. boolVal = True
  2. for b in boolVal:
  3. print(b)
  4. # for b in boolVal:
  5. # TypeError: 'bool' object is not iterable

None类型的空不是可迭代的:

  1. noneVal = None
  2. for n in noneVal:
  3. print(n)
  4. # for n in noneVal:
  5. # TypeError: 'NoneType' object is not iterable

3、TypeError: 'list' object cannot be interpreted as an integer

出错场景:

range内部只能接受整数。而列表转化不成整数,出点类型错误。

  1. nameList = ['小石头', 'xing.org1^', '郭菊锋']
  2. for index in range(nameList):
  3. print(index)
  4. # for index in range(nameList):
  5. # TypeError: 'list' object cannot be interpreted as an integer

修改如下:

先用len获取列表的长度,然后将计算的长度这个数字,放到range内部。

  1. nameList = ['小石头', 'xing.org1^', '郭菊锋']
  2. for index in range(len(nameList)): # 0、1、2
  3. print(index)

4、TypeError: 'tuple' object is not callable

同样是类型错误,说明是该数据类型做了不适合他自己做的事情。
出错场景:

比如下例,我一不小心写了一个用tuple元祖类型的变量调用的bug。本意想获取元祖数据的第一项(下标为0)数据的值,结果脑子短路错把中括号写成了小括号导致的报错:

  1. tupleVal = ('a',1,True)
  2. print(tupleVal(0))
  3. # 打印如下
  4. # print(tupleVal(0)) # TypeError: 'tuple' object is not callable
  5. # TypeError: 'tuple' object is not callable

修改如下:

针对本例,修改为正确的写法,根据偏移量获取数据在列表中也写了,使用中括号包裹偏移量:

  1. tupleVal = ('a',1,True)
  2. print(tupleVal[0]) # 'a'

但是针对此类型的错误,说明元祖类型数据不能当函数调用。

C、名称错误(变量未声明就使用):

1、NameError: name 'xingorg1' is not defined

出错场景:

直接使用一个没有声明的变量,当在本作用域和全局作用域中找不到时,就会发生错误。

  1. print(xingorg1)
  2. # print(xingorg1)
  3. # NameError: name 'xingorg1' is not defined

D、值异常

1、ValueError: invalid literal for int() with base 10: '1.8'

出错场景:

Python 的语法规则,浮点类型的字符串不能使用 int()函数进行强制转换。

  1. print(int('1.8'))
  2. # print(int('1.8'))
  3. # ValueError: invalid literal for int() with base 10: '1.8'

解决方案

虽然浮点形式的字符串,不能使用 int()函数。但浮点数是可以被 int()函数强制转换的

可以先将字符串转换为浮点类型,再将浮点数转换为 int 类型。如下:

  1. print(int(float('1.8')))
  2. # 1

不过对下面这种值异常的情况就无计可施了:

  1. print(int('非整数数字字符串'))
  2. # print(int('非整数数字字符串'))
  3. # ValueError: invalid literal for int() with base 10: '非整数数字字符串'

纯文字类数据,无法转换为整数类型。

2、ValueError: too many values to unpack (expected 2)

出错场景:

表示了这里不应该有两个参数。

  1. nameList = ['小石头', 'xing.org1^', '郭菊锋']
  2. for name,index in nameList:
  3. print(index)
  4. # for name,index in nameList:
  5. # ValueError: too many values to unpack (expected 2)

解决方案

for循环里只用一个变量:

  1. nameList = ['小石头', 'xing.org1^', '郭菊锋']
  2. for name,index in nameList:
  3. print(index)

E、缩进错误

1、IndentationError: expected an indented block

出错场景:

对于 Python 而言,冒号和缩进是一种语法。它会帮助 Python 区分代码之间的层次,理解条件执行的逻辑及先后顺序。

【注:缩进是四个空格或一个 Tab 键】

在语句代码中的冒号“:”后、下一行内容的前面,要有缩进,空几个格。

如果在需要缩进的语句下边没有缩进的代码块,就会报错。

  1. number = 1
  2. if number=='1':
  3. print('1')
  4. # File "main.py", line 3
  5. # print('1')
  6. # ^
  7. # IndentationError: expected an indented block

这是因为当我们去掉缩进时,条件/语句(上边的 if)会和需要执行的命令(上边的 print)成为了两个不同的代码组,属于平行关系。

if 条件下面,缺少了可以执行的动作。那么无论条件成不成立,都不会执行什么操作,这个条件的存在没有任何意义。

解决写法:

加缩进

  1. number = 1
  2. if number=='1':
  3. print('1') # 注意if下边需要执行的命令必须向右缩进

F、偏移量错误

1、IndexError: list index out of range

出错场景:

提取/获取列表中的元素时,我们通常会用列表名[偏移量]的方式来操作。

但是列表可提取的偏移量是有列表的长度决定的。偏移量最小从0开始,最大可用偏移量为列表长度-1

如果你的偏移量大于这个表达式的结果时,就会报下边的错。

  1. xingorg1 = ['小石头', 'xing.org1^', 181, True]
  2. print(xingorg1[4]) # 偏移量超出——IndexError: list index out of range

换句话说,就是偏移量用的大了。

解决写法:

这其实在我们的编程中很难避免。比如这个列表不是你可控制的情况下,你循环中用了这个方法获取就有可能出现“偏移量超标”的情况。

  1. 除了循环中,设定循环的上限为`列表长度-1`以外,
  2. 还可以用容错代码`try...except...`来做异常处理。

G、作用域错误

1、UnboundLocalError: local variable 'xxx' referenced before assignment

出错场景:

报错解释:本地变量‘xxx’在赋值之前引用~

在函数内部的某变量G,此变量被定义了的前提下,在定义之前使用这个变量,就会报错:作用域局部绑定错误。

示例如下:

  1. # 作用域错误 - 局部变量在定义前使用
  2. def UnboundLocalErrorTest():
  3. print(textVar) # 但是提前在赋值之前使用了
  4. textVar = 1 # 定义了该变量
  5. UnboundLocalErrorTest()

⚠️这种千万要区分NameError变量未定义的错误。因为这种的变量已经定义了,只不过是在定义之前使用的。如下:

  1. def UnboundLocalErrorTest():
  2. print(textVar) # 没有定义就直接使用,是变量未定义的错误
  3. UnboundLocalErrorTest()

⚠️这种也要注意使用环境,是在局部函数内部出现的作用域问题,因为如果在全局作用域环境里边,一个定义过的变量在定以前被使用,不会报这种错误,而是报NameError变量未定义的错误。如下:

  1. # 不同于局部未定义错误和局部作用域错误。在全局环境中会有如下表现:
  2. print(globalNameErrorVar) # 但是提前使用,也报未定义错误
  3. globalNameErrorVar = 12 # 虽然定义了

解决写法:

就老实点,定义完了再用白:

  1. def NoUnboundLocalErrorTest():
  2. textVar = 1 # 1、定义
  3. print(textVar) # 2、使用
  4. NoUnboundLocalErrorTest()

H、属性错误(未定义属性获取失败)

1、AttributeError: 'Son' object has no attribute 'familyName'

出错场景:

在类中获取一个未定义的属性时,就会报错

  1. class AttributeError:
  2. def test(self):
  3. print(self.undefinedVar) # 在类中引用未定义的属性
  4. attributeError = AttributeError()
  5. attributeError.test()

或者在子类中,引用父类和子类都没定义的属性,同样也会报这个错误。有点像变量未定义,只不过这个是类中属性未定义。

不过,下边这个例子特殊,父类中明明定义了familyName,为啥调用还是说没这个属性呢?

  1. class Father:
  2. def __init__(self):
  3. self.familyName = '郭'
  4. class Son(Father): # 子类Son继承父类Father
  5. def __init__(self):
  6. print(self.familyName) # AttributeError: 'Son' object has no attribute 'familyName'
  7. son1 = Son()

这是因为这个属性定义在父类的init中。父类Father没有调用,所以init初始化方法不会执行,self.familyName的定义就不会执行。相当于在父类中没有定义这个属性。

解决写法:

第一种情况:
一个类中没定义属性就调用该属性,然后报错了。你说咋解决呢!
两个方法,一是不调用,二是在调用前定义好。

  1. class AttributeError:
  2. def __init__(self):
  3. self.undefinedVar = '提前定义好就能用了'
  4. def test(self):
  5. print(self.undefinedVar) # 这次打印就没问题了。因为属性已经定义了
  6. attributeError = AttributeError()
  7. attributeError.test()

第二种
子类继承父类的情况:
父类的属性不在init方法中定义即可。

  1. class Father:
  2. familyName = '郭哈哈哈'
  3. def language(self):
  4. print(self.familyName)
  5. class Son(Father): # 子类Son继承父类Father
  6. def __init__(self):
  7. self.language()
  8. son1 = Son()

I、解码错误(解码时编码表使用错误):

1、UnicodeDecodeError: 'gbk' codec can't decode byte 0xb4 in position 8: incomplete multibyte sequence

出错场景:

要解码的一个内容,跟他被编码时用的编码表不一致导致报错。

  1. # 先编码
  2. print('小石头'.encode('utf-8')) # b'\xe5\xb0\x8f\xe7\x9f\xb3\xe5\xa4\xb4'
  3. # 再解码
  4. print(b'\xe5\xb0\x8f\xe7\x9f\xb3\xe5\xa4\xb4'.decode('GBK'))
  5. # 把utf-8编码的字符串用GBK来解码,就报错了。
  6. # UnicodeDecodeError: 'gbk' codec can't decode byte 0xb4 in position 8: incomplete multibyte sequence

2、UnicodeDecodeError: 'utf-8' codec can't decode byte 0xce in position 107: invalid continuation byte

出错场景:

使用open()函数读取或写入文件时,需要传入第三个参数表示文件的编码格式。

  1. openResult = open('/Users/.../demo.txt','r',encoding='utf-8')

但是如果encoding=后边的类型和实际demo.txt文件的格式不一致的话,就会报错。

下边是报错的例子:
错误类型与可能原因分析 - 图1

解决方案

  1. 查看txt文件的编码、修改txt文件编码
  2. 或者根据文件的实际编码,修改自己代码中的编码类型。

这里记录如何查看/修改txt文件编码:

1、找到文件,右键点击文件 - 打开方式 - 记事本。

2、在记事本中,左上角点击“文件” - “另存为”。

3、在“另存为”弹窗中查看编码/修改编码(具体位置如下图)
错误类型与可能原因分析 - 图2

J、文件找不到错误(文件查找失败错误):

1、FileNotFoundError: [Errno 2] No such file or directory: '/.../file.txt'

出错场景:

open()函数打开一个文件时、并且第二个参数是读取模式时,若第一个参数的路径错误或者该路径指向的文件根本不存在,就会报文件找不到的错误。

如下代码就报错了:

openResult = open(site + '17-file.txt','r',encoding='utf-8') # 1、打开
# FileNotFoundError: [Errno 2] No such file or directory: '/Users/guojufeng/Documents/GitHub/xingorg1Note/17-file.txt'

原因很简单,就是在路径“/Users/guojufeng/Documents/GitHub/xingorg1Note/”下没有“17-file.txt”这个文件。

但是这个例子比较特殊:路径找不到就报错的前提是: open函数的第二个参数是r、rb、r+、rb+的时候。如果是w和a体系的,就不会报错、并会在该路径下新建同名文件。详细知识点传送