盘一盘 Python中的各种错误类型

it2025-06-25  3

↑↑↑关注后"星标"简说Python

人人都可以简单入门Python、爬虫、数据分析

 简说Python严选 

来源:王的机器    作者:王圣元

One old watch, like brief python

0

引言

用 Python 写代码的流程(flow)可类比成三种演绎故事的形式,按顺序写、按条件写(if)、重复写(while, for),这些都叫做流程控制(control flow)。

按顺序:一句一句写

按条件:用 if 语句

按重复:

用 for 循环 - 当循环次数事先知道

用 while 循环 - 当循环次数事先不知道

前提是代码运行不出错。如果出错了需要异常处理(exception handling)。处理异常或错误我们首先要知道它们的类型,才能有的放矢。这就是本贴的内容

本帖的内容如下:

从高层面了解三大错误类型

从具体层面了解常见错误类型

用面向对象编程的期权定价例子来说明

1

三类错误

程序中的错误(error)又称 bug,可以分为三大类:

语法错误(syntax error)

运行错误(runtime error)

逻辑错误(logical error)

先看下图的总结。

语法错误

语法错误顾名思义就是没有遵循 Python 语言的语法,在程序编译(compliation)时报错,而且容易识别。语法错误的常见例子有:

关键词拼错:print 打成 primt

函数最后没带冒号:def fun()

字符串最后没带引号:'error

括号不匹配:print(

缩进位置错误

等等。

分析上图具体的中文和 Python 代码的语法错误例子:

# 中文 昨天,送给我几本书。 # Python 代码 print('I love you)

那句中文缺少主语。

那句代码字符串没有引号。

运行错误

运行错误顾名思义是在程序运行时报错,不太容易识别。因为有些错误真的是你不运行根本不知道这里会出错,除非你过去有丰富的经验。运行错误的常见例子有:

分母为零

整数加字符串

使用没有定义的变量名

调用没有定义的函数

读取不存在的文件

等等。

分析上图具体的中文和 Python 代码的运行错误例子:

# 中文 我飞到月球去看风景。 # Python 代码 a = 10 b = 0 c = a/b

那句中文中的“我飞到月球去看风景”这句话没有语法错误,但是实操时根本不可行。

那句代码在做除法时中分母为零。

逻辑错误

逻辑错误在程序运行时根本不报错,只是产出不是想要的结果,因此很难识别。逻辑错误的常见例子有:

用错变量名

缩进错了整块代码

用错操作符优先级

用错布尔表达式

等等。

分析上图具体的中文和 Python 代码的逻辑错误例子:

# 中文 因为我满仓入市,所以股市一定涨。 # Python 代码 (a, b) = (10, 8) print('The mean of a and b is', a+b/2)

那句中文虽然没任何语法错误,也可能发生(运气好赌对了),但是毫无逻辑。

那句代码想求 a 和 b 的均值,应该写成 (a+b)/2 但是写成 a+b/2。

2

具体错误

由下图所示,程序开始时有两种可能,1. 没报错,2. 报错。没报错时程序按照顺序、按照条件语句(if),按照循环语句(for, while)跑,如果报错了 Python 会给你很详细的信息。

下表是最齐全的错误层级表,每个错误类型都是 BaseException 的子类,而我们一般讲的异常处理是 Exception 下面的子类。

接下来我们就来看看常见的错误类型(下表粉色)。

BaseException +-- SystemExit +-- KeyboardInterrupt +-- GeneratorExit +-- Exception +-- StopIteration +-- ArithmeticError | +-- FloatingPointError | +-- OverflowError | +-- ZeroDivisionError +-- AssertionError +-- AttributeError +-- BufferError +-- EOFError +-- ImportError +-- LookupError | +-- IndexError | +-- KeyError +-- MemoryError +-- NameError | +-- UnboundLocalError +-- OSError | +-- BlockingIOError | +-- ChildProcessError | +-- ConnectionError | | +-- BrokenPipeError | | +-- ConnectionAbortedError | | +-- ConnectionRefusedError | | +-- ConnectionResetError | +-- FileExistsError | +-- FileNotFoundError | +-- InterruptedError | +-- IsADirectoryError | +-- NotADirectoryError | +-- PermissionError | +-- ProcessLookupError | +-- TimeoutError +-- ReferenceError +-- RuntimeError | +-- NotImplementedError +-- SyntaxError | +-- IndentationError | +-- TabError +-- SystemError +-- TypeError +-- ValueError | +-- UnicodeError | +-- UnicodeDecodeError | +-- UnicodeEncodeError | +-- UnicodeTranslateError +-- Warning +-- DeprecationWarning +-- PendingDeprecationWarning +-- RuntimeWarning +-- SyntaxWarning +-- UserWarning +-- FutureWarning +-- ImportWarning +-- UnicodeWarning +-- BytesWarning +-- ResourceWarning

由于代码太过于简单,几乎不需要额外解释。

SyntaxError

SyntaxError

print('字符串最后没有单引号) File "<ipython-input-6-ec1f762dc7cc>", line 1     print('函数最后没有小括号'                      ^ SyntaxError: unexpected EOF while parsing print('函数最后没有小括号' File "<ipython-input-6-ec1f762dc7cc>", line 1     print('函数最后没有小括号'                      ^ SyntaxError: unexpected EOF while parsing

IndentationError

作为 SyntaxError 的子类,当缩进有问题时报错。

if True: print('缩进有问题') File "<ipython-input-8-6e20bad23f95>", line 2     print('缩进有问题')         ^ IndentationError: expected an indented block

NameError

NameError

not_defined --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-19-f59b2fe187d5> in <module> ----> 1 not_defined NameError: name 'not_defined' is not defined

UnboundLocalError

作为 SyntaxError 的子类,当局部变量被引用前没有赋值时报错。

def fun(): a = a + 1 fun() --------------------------------------------------------------------------- UnboundLocalError Traceback (most recent call last) <ipython-input-26-ffaf665429bf> in <module>       2     a = a + 1       3  ----> 4 fun() <ipython-input-26-ffaf665429bf> in fun()       1 def fun(): ----> 2 a = a + 1       3        4 fun() UnboundLocalError: local variable 'a' referenced before assignment

LookupError

IndexError

作为 LookupError 的子类,当列表的索引超出范围时报错(对元组也适用)。

l = [1, 2, 3] l[1031] --------------------------------------------------------------------------- IndexError Traceback (most recent call last) <ipython-input-27-e0d31b3ef28e> in <module>       1 l = [1, 2, 3] ----> 2 l[1031] IndexError: list index out of range

KeyError

作为 LookupError 的子类,当字典的键没有定义时报错。

d = {'code':'JD', 'price':42} d['CEO'] --------------------------------------------------------------------------- KeyError Traceback (most recent call last) <ipython-input-28-54414ce3d92d> in <module>       1 d = {'code':'JD', 'price':42} ----> 2 d['CEO'] KeyError: 'CEO'

ArithmeticError

ZeroDivisionError

作为 ArithmeticError 的子类,当做除法分母为零时报错。

1/0 --------------------------------------------------------------------------- ZeroDivisionError Traceback (most recent call last) <ipython-input-33-9e1622b385b6> in <module> ----> 1 1/0 ZeroDivisionError: division by zero

OverflowError

作为 ArithmeticError 的子类,当运算结果太大而不能被表示时报错。

import math math.exp(1031) --------------------------------------------------------------------------- OverflowError Traceback (most recent call last) <ipython-input-47-daa1e6fe64b9> in <module>       1 import math ----> 2 math.exp(1031) OverflowError: math range error

FloatingPointError

作为 ArithmeticError 的子类,以 numpy 里的操作为例,只有当把 seterr 中的参数 invalid 设置 'raise' 时,当给负数开根号时报错。

import numpy numpy.seterr(invalid='raise') numpy.sqrt(-1) --------------------------------------------------------------------------- FloatingPointError Traceback (most recent call last) <ipython-input-59-3619e85afd49> in <module>       1 import numpy       2 numpy.seterr(invalid='raise') ----> 3 numpy.sqrt(-1) FloatingPointError: invalid value encountered in sqrt

TypeError

当某种操作不兼容两种不同类型的变量时报错(比如整数加字符串)。

1031 + '1031' --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-61-95f206b79753> in <module> ----> 1 1031 + '1031' TypeError: unsupported operand type(s) for +: 'int' and 'str'

ValueError

当对函数传入无效的参数时报错。

int('@') --------------------------------------------------------------------------- ValueError Traceback (most recent call last) <ipython-input-62-29f13fe27c63> in <module> ----> 1 int('@') ValueError: invalid literal for int() with base 10: '@'

AttributeError

当对象没有某种属性而被调用时报错(比如整型对象没有 append 方法,这是列表对象里的方法)。

a = 1 a.append(2) --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-65-1a0b9c61ae63> in <module>       1 a = 1 ----> 2 a.append(2) AttributeError: 'int' object has no attribute 'append'

OSError

操作系统错误的类别。

FileNotFoundError

作为 OSError 的子类,当要打开的文件不存在时报错。

f = open('No Such File.txt') --------------------------------------------------------------------------- FileNotFoundError Traceback (most recent call last) <ipython-input-67-48a6865b4125> in <module> ----> 1 f = open('No Such File.txt') FileNotFoundError: [Errno 2] No such file or directory: 'No Such File.txt'

ImportError

当导入模块下的函数失败时报错,比如 numpy 中 没有 sqr 方法,只有 sqrt 方法。

from numpy import sqr --------------------------------------------------------------------------- ImportError Traceback (most recent call last) <ipython-input-72-1c9f27eff610> in <module> ----> 1 from numpy import sqr ImportError: cannot import name 'sqr' from 'numpy' (C:\Users\oawsy\AppData\Local\Continuum\anaconda3\lib\site-packages\numpy\__init__.py)

ModuleNotFoundError

当导入模块不存在时报错,比如将 numpy 误打成 numqy。

import numqy --------------------------------------------------------------------------- ModuleNotFoundError Traceback (most recent call last) <ipython-input-68-c1372635685c> in <module> ----> 1 import numqy ModuleNotFoundError: No module named 'numqy'

StopIteration

当在迭代器中使用 next() 函数超出其所含元素个数的范围时报错。

i = iter([1,2,3]) i <list_iterator at 0x25af5c859e8> print(next(i)) print(next(i)) print(next(i)) print(next(i)) --------------------------------------------------------------------------- StopIteration Traceback (most recent call last) <ipython-input-84-ce53e5485e54> in <module>       2 print(next(i))       3 print(next(i)) ----> 4 print(next(i)) StopIteration:

3

具体实例

以用 OOP 来编写 Black-Scholes 解析解为例。首先引用 numpy 和 scipy 包下的函数。

from numpy import log, sqrt, exp from scipy import stats

编写以下 BSM 类来计算期权价格。

创建一个看涨期权对象。

opt = BSM('Call', 100, 105, 0.05, 0, 1, 0.2) type(opt) __main__.BSM

计算其期权价值,没有报错。

opt.value() 8.021352235143176

但是如果不小心的话,可能会犯以下错误。

比如忘记打反括号 - SyntaxError

opt.value( File "<ipython-input-21-82b81dd97516>", line 1     opt.value(               ^ SyntaxError: unexpected EOF while parsing

比如把 value() 记成了 price() - AttributeError

opt.price() --------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-22-08da04670da7> in <module> ----> 1 opt.price() AttributeError: 'BSM' object has no attribute 'price'

比如把 opt 打成了 opt1 - NameError

opt1.value() --------------------------------------------------------------------------- NameError Traceback (most recent call last) <ipython-input-23-63b689f52380> in <module> ----> 1 opt1.value() NameError: name 'opt1' is not defined

比如将 S0 的数值 100 输成了 '100' - TypeError

opt1 = BSM('Call', '100', 105, 0.05, 0, 1, 0.2) opt1.value() --------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-24-46a0ecb04b28> in <module>       1 opt1 = BSM('Call', '100', 105, 0.05, 0, 1, 0.2) ----> 2 opt1.value() <ipython-input-18-9e07cba9d523> in value(self)      18       19     def value(self): ---> 20         return self.omega * (self.S0*exp(-self.q*self.T)*stats.norm.cdf(self.omega*self.d1()) \      21                              - self.K*exp(-self.r*self.T)*stats.norm.cdf(self.omega*self.d2())) TypeError: can't multiply sequence by non-int of type 'numpy.float64'

虽然以上的错误看起来有些弱智,但是用户在输入时指不定出什么幺蛾子,各种情况都要考虑进来保证程序不会崩。

4

总结

三大错误类型:语法错误(容易识别),运行错误(较易识别)和逻辑错误(不易识别)。

最常见错误类型:

SyntaxError(语法报错)

IndexError(序列中没有该索引)

KeyError(字典中没有该键)

ValueError(传入无效参数)

NameError(未声明/初始化对象 )

TypeError(对不同类型操作无效)

AttributeError(调用对象中不存在的属性)

本帖将用 Python 编程的错误做了个系统的梳理,then so what?有错就要改不是吗?这就是下帖的内容,异常处理(exception handling)。

本书参加当当每满100减50的活动

优惠码:STCBMN

简说Python 长按扫码关注,一起学Python 学习更多: 整理了我开始分享学习笔记到现在超过250篇优质文章,涵盖数据分析、爬虫、机器学习等方面,别再说不知道该从哪开始,实战哪里找了
最新回复(0)