在线代码运行BanShow Run

Python 常见报错与原因

Python 常见报错对照表,每一节标题就是你会在屏幕上看到的报错原文,下面给出原因和改法。可以复制到浏览器里亲手触发一遍,比背教程记得牢。

打开 Python 运行器 →

SyntaxError: invalid syntax

原因:代码不符合 Python 语法规则,程序根本没能开始运行。

python
# 常见触发方式
print("缺少右括号"     # SyntaxError: '(' was never closed
if True               # SyntaxError: expected ':'
    pass
name = "小明"
print(name)           # SyntaxError: 用了中文全角括号
x = 3
print(f"值是 {x}")     # 正确
print(f"值是 {x}")     # f-string 的花括号里必须放表达式

怎么修:看报错里的 line N 和那个 ^ 箭头指向的位置。真正的错误经常在上一行——比如上一行少了个括号,Python 会一直读到下一行才发现。中文标点(()"":,)是初学者最常见的元凶。

IndentationError

原因:Python 用缩进表示代码块,缩进不一致就会报错。

python
# expected an indented block after 'if' statement on line 1
if True:
print("没有缩进")

# unindent does not match any outer indentation level
def f():
    a = 1
     b = 2      # 多了一个空格

# 混用 Tab 和空格:Tab 缩进不一致

怎么修:一个代码块统一用 4 个空格。CodeMirror 里按 Tab 会自动插入 4 个空格,但如果你从别处粘贴了带 Tab 的代码,可能就会混用。选中出错那几行重新缩进即可。

NameError: name 'xxx' is not defined

原因:用了一个从没赋值过的名字,绝大多数是拼写错误。

python
score = 90
print(Score)        # NameError: name 'Score' is not defined(大小写敏感)
print(socre)        # NameError: 手滑打错

# 另一种情况:变量定义在 if / 函数里,外面访问不到
if False:
    temp = 1
print(temp)         # NameError: name 'temp' is not defined

怎么修:Python 严格区分大小写。报错信息里引号中的名字就是它没找到的那个,拿它去代码里搜一遍。

TypeError

原因:对某种类型做了它不支持的操作。

python
age = 18
print("年龄:" + age)        # TypeError: can only concatenate str (not "int") to str
print("年龄:" + str(age))   # 正确
print("年龄:", age)         # 正确,print 的逗号会自动转字符串
print(f"年龄:{age}")        # 正确,f-string 自动转

len(123)                     # TypeError: object of type 'int' has no len()
"abc"[0] = "x"               # TypeError: 'str' object does not support item assignment
sorted([1, "a"])             # TypeError: '<' not supported between instances of 'str' and 'int'
max([1, 2, 3], [4])          # TypeError: 参数用错了

怎么修:input() 返回的永远是字符串,要参与运算必须先 int() 或 float()。字符串不可修改,想改就用切片重新拼一个。

IndexError: list index out of range

原因:下标超出了列表长度。列表下标从 0 开始,最后一个元素是 len(列表) - 1。

python
nums = [10, 20, 30]
print(nums[3])       # IndexError,最大合法下标是 2
print(nums[-4])      # IndexError,负下标最小是 -3
print(nums[len(nums)])   # 经典错误:应该是 len(nums) - 1

for i in range(len(nums) + 1):   # 多循环了一次
    print(nums[i])               # 最后一轮 IndexError

怎么修:循环遍历元素优先用 for x in nums,需要下标时用 for i, x in enumerate(nums),能彻底避开这类错误。

KeyError: 'xxx'

原因:字典里没有这个键,却用 d[key] 去取。

python
user = {"name": "小明", "age": 18}
print(user["Name"])          # KeyError: 'Name'(大小写敏感)
print(user["city"])          # KeyError: 'city'

# 安全写法
print(user.get("city"))          # None,不报错
print(user.get("city", "未知"))  # 给默认值
if "city" in user:               # 先判断
    print(user["city"])

怎么修:get() 是最省事的方案。注意 d.get(k) 返回 None 时,后面再对它做 ["x"] 或 .split() 会接着报 TypeError: 'NoneType' object is not subscriptable。

ValueError

原因:类型对,但值本身没法转换或不合法。

python
int("abc")            # ValueError: invalid literal for int() with base 10: 'abc'
int("18 岁")          # ValueError
int(input())          # 如果用户在输入框里敲了空行或字母,就会 ValueError
float("3,14")         # ValueError: 小数点是 . 不是 ,
x = 5
y = 1, 2              # 手滑写成元组
a, b = y              # 有时反而"成功",但语义错了

怎么修:转换用户输入时永远包一层 try。

python
while True:
    try:
        age = int(input("年龄:"))
        break
    except ValueError:
        print("请输入数字")

ZeroDivisionError: division by zero

原因:除数是 0。求平均值时列表为空也会踩到这个。

python
print(10 / 0)         # ZeroDivisionError: division by zero
nums = []
print(sum(nums) / len(nums))    # 求平均值时列表为空 → ZeroDivisionError

# 先判空
print(sum(nums) / len(nums) if nums else 0)

注意:10 / 0.0 在 Python 里同样报错,不会像某些语言那样得到 inf。想得到无穷大要写 float("inf")。

AttributeError

原因:对象没有你调用的那个属性或方法,常见于拼错方法名或对错误的类型调用方法。

python
"abc".upper()          # 正确
"abc".uppper()         # AttributeError: 'str' object has no attribute 'uppper'
[1, 2].add(3)          # AttributeError: 'list' object has no attribute 'add'(集合才有 add,列表是 append)
(1, 2).append(3)       # AttributeError: 元组不可修改
None.strip()           # AttributeError: 'NoneType' object has no attribute 'strip'

nums = [3, 1]
result = nums.sort()   # sort() 原地排序,返回 None
print(result.append(2))   # AttributeError,因为 result 是 None

怎么修:看清报错里 'xxx' object has no attribute 'yyy'——前面是对象的实际类型,后面是你写的名字。如果类型是 NoneType,说明上一步返回了 None(sort()、reverse()、print()、list.append() 都返回 None)。

ModuleNotFoundError: No module named 'xxx'

原因:这个库不在浏览器里的 Python 环境中。

python
import numpy        # ModuleNotFoundError
import pandas       # ModuleNotFoundError
import requests     # ModuleNotFoundError
import matplotlib   # ModuleNotFoundError

为什么:本站的 Python 运行在浏览器的 WebAssembly 里,只带标准库,第三方库需要联网下载编译好的包,纯前端离线环境不支持。

能用的:math random json re datetime collections itertools functools statistics decimal fractions string csv io os.path textwrap heapq bisect copy time calendar base64 hashlib unicodedata 等标准库全部可用。

python
# 想要 numpy 的效果,标准库也能做
import statistics, math
data = [1, 2, 3, 4, 5]
print(statistics.mean(data), statistics.stdev(data))
print([math.sqrt(x) for x in data])

UnboundLocalError

原因:在函数里给一个外部变量赋值,Python 就把它当成本地变量,赋值前读取会报错。

python
count = 0

def add():
    count += 1        # UnboundLocalError: cannot access local variable 'count'

# 修法一:用 global 声明
def add_ok():
    global count
    count += 1

# 修法二(更好):传参并返回,不依赖全局变量
def add_pure(c):
    return c + 1

RecursionError: maximum recursion depth exceeded

原因:递归没有正确的终止条件,或者递归层数太深(默认上限 1000)。

python
def f(n):
    return f(n)          # 忘了 n-1,无限递归

def fib(n):
    return n if n < 2 else fib(n - 1) + fib(n - 2)

print(fib(30))           # 慢,但能跑
# print(fib(1500))       # RecursionError,而且非常慢

# 修法:改成循环,或者加缓存
from functools import lru_cache

@lru_cache(maxsize=None)
def fib_fast(n):
    return n if n < 2 else fib_fast(n - 1) + fib_fast(n - 2)

EOFError: EOF when reading a line

原因:input() 调用次数超过了「输入 (stdin)」面板里给的行数。

python
name = input()
age = input()
city = input()      # 如果 stdin 只有两行,这一行就 EOFError

怎么修:确保 stdin 面板的行数 ≥ 代码里 input() 的调用次数(注意循环里的 input() 会调用多次)。可以用 try 兜底:

python
try:
    line = input()
except EOFError:
    line = ""

报错信息怎么读

Python 的 traceback 从下往上读,最后一行才是真正的错误:

text
Traceback (most recent call last):
  File "<exec>", line 12, in <module>
  File "<exec>", line 5, in check
TypeError: can only concatenate str (not "int") to str
  • 第 1 行 Traceback (most recent call last) —— 表示下面是调用栈,按「最近的调用在最后」排列。
  • 中间每一行 File "...", line N, in 函数名 —— 从上往下是你程序执行的调用路径。line 12 是入口,line 5 是出错的具体位置。
  • 最后一行 TypeError: ... —— 错误类型 + 具体说明,先读这一行。
  • 本站还会在报错下面用波浪线标出出错的那一行代码。

逻辑不报错但结果不对

这类问题最难查,因为程序正常运行。用 print 把中间值打出来是最有效的办法:

python
nums = [5, 2, 9, 1]
total = 0
for n in nums:
    total = n          # 应该是 total += n,写成 = 每次都被覆盖
    print("调试:", n, total)
print("和:", total)    # 输出 1,不是 17

其他高频陷阱:

  • nums.sort() 返回 None,要用 sorted(nums) 才有返回值。
  • 整数除法用 / 得到浮点数,// 才是取整,% 是取余。
  • if x = 1 是语法错误,判断相等要用 ==。
  • 比较浮点数不要用 ==,用 abs(a - b) < 1e-9。
  • 浅拷贝 b = a 只是给同一个列表起了第二个名字,改 b 会影响 a;要真正复制用 b = a.copy() 或 b = list(a)。

换一门语言