资讯动态

Python编程中常见的错误及其解决方法总结

发布时间:2026/10/13 12:09:01 来源:尧图企业网站定制
前言新手面对报错时的第一反应往往是「代码挂了重写一遍」。但有经验的人会先做另一件事把报错信息读完。Python 的报错信息里其实已经把「出了什么事、在哪一行、当时是什么类型」写得相当清楚3.10 之后还进一步加了更精确的位置提示和「你是不是想写……」的猜测。所以要先把本文的范围划清楚这一篇只讲「怎么读报错」不讲「怎么捕获」。try/except那套机制属于另一个话题本文一次都不涉及。这里的目标是让你看到一个报错时能在十秒内定位到「哪一行、哪类问题、下一步看什么」。本文按报错的来源分四组讲语法层代码根本没被接受、名字与属性与类型层代码在跑但用错了东西、查找层容器里没这个元素、导入层模块找不到。每一组都给出真实的报错文本逐行拆解。一、报错信息的三段结构不管哪类错误Python 打印的格式都遵循同一套模板Traceback (most recent call last):File demo.py, line 7, in moduletotal price count~~~~~~^~~~~~~TypeError: unsupported operand type(s) for : float and str从上往下读三样东西File demo.py, line 7—— 出事的位置。有多个File块时最后一个是直接出事的那一行上面的是调用它的地方。中间被引出来的那行源码以及它下面那串^或~~~—— 精确指出这一行的哪一段出了问题。3.11 之后这种「下划波浪线」标注变得很常见它标出的就是参与运算的那个表达式。最后一行—— 异常类型冒号后面是消息。类型决定「哪一类问题」消息决定「具体是什么问题」。记住这个口诀看最后一行定类型看倒数第二个 File 块定位置看波浪线定范围。二、语法层SyntaxError 与 IndentationError这两类错误有个共同特点代码压根没开始执行。解释器在解析阶段就拒绝了所以不会有「运行时」的信息你看到的永远是「文件第几行写得不对」。File demo.py, line 1print hello^^^^^^^^^^^^^SyntaxError: Missing parentheses in call to print. Did you mean print(...)?这是把 Python 2 的老代码拿到 Python 3 里跑的最典型症状。Python 2 里print是语句可以不写括号Python 3 里print是函数括号是必须的。报错消息里那句猜测已经直接给了答案。顺带说Python 2.7 已于 2020 年 1 月 1 日停止维护这类改写是接手老项目时的必做项。File demo.py, line 3return x^^^^^^^^SyntaxError: return outside functionreturn只能出现在函数体内。看到这个报错检查缩进层级——很可能上面那个def已经结束了这一行掉到了模块顶层。File demo.py, line 4total a ^SyntaxError: invalid syntaxinvalid syntax是最笼统的一类但配上波浪线就很好办它指向的位置通常就是「读到这儿读不下去了」。像这个例子加号后面缺了操作数所以光标落在行尾。遇到invalid syntax往指示位置的前面看而不是往后看——错误往往出在它前一个记号上。File demo.py, line 5print(done)^IndentationError: unexpected indentFile demo.py, line 5x 1IndentationError: expected an indented blockunexpected indent是「不该缩进却缩进了」常见于从别处复制粘代码、多打了一个空格。expected an indented block是「该缩进却没缩进」通常出现在if、for、def这类冒号之后。还有一种是前两者的亲戚TabError: inconsistent use of tabs and spaces in indentation同一个文件里混用了制表符和空格。肉眼看缩进是对齐的但解释器数的是字符。统一用空格PEP 8 建议 4 个空格就能根治。三、名字、属性与类型NameError、AttributeError、TypeError这一层是运行时错误代码真的跑起来了跑到某一行时发现「这个东西不对劲」。NameError: name totl is not defined. Did you mean: total?意思是「这个名字我从来没听说过」。常见成因有四种按出现频率排拼写错误如上面这个。变量在赋值之前就被使用。忘了import直接用json.dumps却从没import json。作用域问题在函数内部读取了一个只在别处定义的名字。那半句Did you mean:是 Python 3.10 起加入的解释器会在当前作用域里找相似名字非常省事。它的一个变体要单独认UnboundLocalError: cannot access local variable count where it is not associated with a value名字确实存在但它在函数里被赋过值于是成了局部变量而在被读取的那一刻这个局部变量还没有值。典型场景是函数里既读又写同一个名字却在读的时候还没走到写的那一步。这句话的措辞在不同版本里不一样较新的版本会直说「不能访问尚未绑定值的局部变量」更早的版本写的是「局部变量在赋值之前被引用」。两种说法指的是同一件事看到旧措辞不要以为换了机制。AttributeError: str object has no attribute append. Did you mean: extend?意思是「str这个类型的对象上没有append这个方法」。读法是先看类型再看方法名。str说明你手上是一个字符串而字符串是不可变的没有追加元素的方法——append是列表的方法。这里的根因几乎总是「变量在半路被赋值成了别的类型」。TypeError: unsupported operand type(s) for : int and strTypeError: can only concatenate str (not int) to strTypeError: int object is not callableunsupported operand type(s) for 是「这两个类型不能做这个运算」can only concatenate str (not int)是它针对字符串加法的专门措辞int object is not callable则是「你对一个整数用了调用语法」最常见的原因是变量名遮蔽了函数名——比如先定义了def list(): ...后来又list [1, 2]于是list()就调不动了。TypeError的读法固定为三步看运算符或方法名、看两侧或对象的类型、回到那一行确认变量到底是什么。四、查找与导入KeyError、IndexError、ModuleNotFoundErrorKeyError: name字典里没有name这个键。报错消息里被引号包住的那段就是这个键本身非常直白。如果键是字符串且里面有空格或特殊字符有时会看到双重引号把内容按原样读出来即可。排查时通常要回头确认「写进去的时候用的是哪个键」——是name还是Name是字符串还是数字。IndexError: list index out of range下标超出了序列范围。注意它不带具体数值所以要自己回到那一行看用的是哪个下标。常见成因用len(lst)当下标最大值应该是len(lst) - 1、迭代过程中删元素导致长度变了、把空列表当成有内容的列表来取。ModuleNotFoundError: No module named requests导入的模块找不到。按顺序排查模块名拼写是否正确模块名大小写敏感。标准库还是第三方库——requests不是标准库没装就是没有。装法是pip install requests具体包名以该库官方文档为准。是不是自己写的文件比如同目录下有utils.py却import util。若是包还要看它有没有__init__.py、是否在sys.path里。虚拟环境是否激活装在了另一个环境里是最常见的「明明装了却说没有」。ModuleNotFoundError是ImportError的子类所以在老的英文资料里常看到ImportError: No module named ...这种写法那是更早版本的措辞。下面这张表把最常见的一批报错压成速查表报错一句话含义先看什么SyntaxError语法没通过代码没执行波浪线位置的前一个记号IndentationError缩进层级不对冒号后的缩进、是否混用 TabNameError名字不存在拼写、是否import过UnboundLocalError局部变量还没赋值就被读函数内的赋值语句位置TypeError类型不支持这个操作运算符两侧的类型AttributeError对象没这个属性/方法对象实际是什么类型KeyError字典没这个键键的拼写与类型IndexError下标越界下标表达式与序列长度ModuleNotFoundError模块找不到是否安装、环境是否正确常见坑点1. 只看第一行Traceback就下结论❌ 一看到Traceback (most recent call last):就以为是第一段File出了问题。 ✅ 先看最后一行确定异常类型再看最后一个File块确定直接出事的行。2. 把invalid syntax的位置当成错误所在❌ 紧盯着波浪线指向的那个字符反复检查。 ✅ 解析器是「读到读不动了」才报错问题常常在它前面一个记号少个括号、少个逗号、少个冒号。3. 以为NameError一定是拼错❌ 把名字逐字母核对三遍仍找不到原因。 ✅ 检查三件事有没有import、是不是在赋值之前使用、是不是在函数里访问了不该访问的作用域。4. 把AttributeError的成因归到方法不存在❌ 去查文档确认append到底叫什么。 ✅ 先看报错里的类型str object确认这个变量实际是什么类型多数时候是类型在半路变了。5. 用len()当最后一个下标❌lst[len(lst)]直接越界。 ✅ 最后一个下标是len(lst) - 1for循环里用enumerate拿下标更稳。6. 看到ModuleNotFoundError就反复重装❌ 一遍遍pip install问题照旧。 ✅ 先确认当前用的是哪个 Python 环境、装在哪个解释器下虚拟环境没激活是高频原因。7. 把 Python 2 的老代码直接跑在 Python 3 上❌print x、except X, e、raise X, y、dict.iteritems()、xrange这类写法直接搬过来。 ✅ 分别为print(x)except X as eraise X(y).items()range。Python 2.7 已于 2020 年 1 月 1 日停止维护老写法只是为了读懂遗留代码。8. 遇到报错就吞掉靠猜改代码❌ 加一句pass让程序继续跑报错看不到了问题也还在。 ✅ 先把报错信息读懂、定位到具体那一行再决定怎么改报错不是噪音它是现场记录。总结层次代表报错读法要点语法层SyntaxError、IndentationError、TabError代码未执行看指示位置的前一个记号、看缩进名字/属性/类型层NameError、UnboundLocalError、AttributeError、TypeError看类型、看方法名、看变量在半路被改成了什么查找层KeyError、IndexError键直接写在消息里下标要自己回查导入层ModuleNotFoundError拼写、是否安装、环境是否正确读报错是一项可以练出来的技能而且性价比极高必须先定位到那一行才谈得上修。最后一行给你类型倒数第二个File块给你行号那串波浪线给你范围——把这三样读全再动手多数问题不必靠猜。

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价 →
↑