本文目录导读:

我来系统地介绍Python代码报错的修复方法和常见案例。
理解错误信息
错误类型识别
# 常见错误类型 # SyntaxError - 语法错误 # NameError - 名称错误 # TypeError - 类型错误 # ValueError - 值错误 # IndexError - 索引错误 # KeyError - 键错误 # AttributeError - 属性错误
读懂错误信息
# 示例:分析错误
try:
result = 10 / 0
except ZeroDivisionError as e:
print(f"错误类型:{type(e).__name__}")
print(f"错误信息:{str(e)}")
print(f"错误位置:{e.__traceback__.tb_lineno}")
常见错误修复案例
案例1:SyntaxError语法错误
# 错误代码
# if True
# print("Hello")
# 修复代码
if True:
print("Hello")
# 常见语法错误:
# 1. 缺少冒号
# for i in range(5) # 缺少冒号
for i in range(5):
pass
# 2. 缩进错误
# def func():
# print("hello") # 缩进不一致
def func():
print("hello") # 正确缩进
# 3. 括号不匹配
# print("hello" # 缺少右括号
print("hello") # 添加右括号
案例2:NameError名称错误
# 错误代码
# print(undefined_variable)
# 修复方法
# 方法1:定义变量
undefined_variable = 10
print(undefined_variable)
# 方法2:使用条件检查
if 'undefined_variable' in locals():
print(undefined_variable)
else:
print("变量未定义")
# 方法3:使用默认值
variable = undefined_variable if 'undefined_variable' in dir() else None
案例3:TypeError类型错误
# 错误代码
# result = "数字是:" + 10 # 字符串和整数不能直接拼接
# 修复代码
# 方法1:类型转换
result = "数字是:" + str(10)
print(result)
# 方法2:使用f-string
result = f"数字是:{10}"
print(result)
# 方法3:使用format
result = "数字是:{}".format(10)
print(result)
# 方法4:类型检查
def add_numbers(a, b):
if not isinstance(a, (int, float)):
raise TypeError(f"参数a必须是数字,得到{type(a)}")
if not isinstance(b, (int, float)):
raise TypeError(f"参数b必须是数字,得到{type(b)}")
return a + b
# 测试
print(add_numbers(5, 3)) # 正确
# print(add_numbers(5, "3")) # 抛出错误
案例4:ValueError值错误
# 错误代码
# number = int("abc") # 字符串不能转换为整数
# 修复方法
# 方法1:异常处理
try:
number = int("abc")
except ValueError as e:
print(f"转换失败:{e}")
number = 0 # 设置默认值
# 方法2:验证输入
user_input = "abc"
if user_input.isdigit():
number = int(user_input)
else:
print("输入不是有效的数字")
number = 0
# 方法3:安全转换函数
def safe_int(value, default=0):
try:
return int(value)
except (ValueError, TypeError):
return default
print(safe_int("abc")) # 返回0
print(safe_int("123")) # 返回123
案例5:IndexError索引错误
# 错误代码
# my_list = [1, 2, 3]
# print(my_list[5]) # 索引超出范围
# 修复方法
my_list = [1, 2, 3]
# 方法1:检查索引范围
index = 5
if 0 <= index < len(my_list):
print(my_list[index])
else:
print(f"索引{index}超出范围")
# 方法2:使用try-except
try:
print(my_list[5])
except IndexError:
print("索引超出列表范围")
# 方法3:安全访问函数
def safe_get(lst, index, default=None):
try:
return lst[index]
except IndexError:
return default
print(safe_get(my_list, 5)) # 返回None
print(safe_get(my_list, 1)) # 返回2
案例6:KeyError键错误
# 错误代码
# my_dict = {"name": "Alice", "age": 30}
# print(my_dict["gender"]) # 键不存在
# 修复方法
my_dict = {"name": "Alice", "age": 30}
# 方法1:使用get方法
print(my_dict.get("gender")) # 返回None
print(my_dict.get("gender", "未知")) # 返回默认值
# 方法2:检查键是否存在
if "gender" in my_dict:
print(my_dict["gender"])
else:
print("键不存在")
# 方法3:使用defaultdict
from collections import defaultdict
safe_dict = defaultdict(lambda: "默认值", my_dict)
print(safe_dict["gender"]) # 返回"默认值"
# 方法4:异常处理
try:
print(my_dict["gender"])
except KeyError:
print("键不存在,使用默认值")
案例7:AttributeError属性错误
# 错误代码
# number = 10
# number.append(5) # 整数没有append方法
# 修复方法
# 方法1:类型检查
def safe_append(obj, value):
if hasattr(obj, 'append'):
obj.append(value)
return obj
else:
print(f"{type(obj)}类型不支持append操作")
return None
# 测试
my_list = [1, 2, 3]
safe_append(my_list, 4)
print(my_list) # [1, 2, 3, 4]
# 方法2:使用try-except
number = 10
try:
number.append(5)
except AttributeError as e:
print(f"属性错误:{e}")
# 方法3:使用getattr
class Person:
def __init__(self, name):
self.name = name
def greet(self):
return f"Hello, I'm {self.name}"
person = Person("Alice")
greeting_method = getattr(person, 'greet', lambda: "方法不存在")
print(greeting_method()) # Hello, I'm Alice
non_exist = getattr(person, 'nonexistent', "属性不存在")
print(non_exist) # 属性不存在
调试技巧
使用断言
def divide(a, b):
assert b != 0, "除数不能为零"
return a / b
# 测试
try:
print(divide(10, 0))
except AssertionError as e:
print(f"断言失败:{e}")
使用logging
import logging
# 配置日志
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(levelname)s - %(message)s'
)
def process_data(data):
logging.debug(f"处理数据:{data}")
if not data:
logging.warning("数据为空")
return None
try:
result = data['value'] * 2
logging.info(f"处理结果:{result}")
return result
except KeyError as e:
logging.error(f"缺少键:{e}")
return None
# 测试
process_data({'value': 5}) # 正常工作
process_data({}) # 缺少键
process_data(None) # 数据为空
使用traceback
import traceback
def buggy_function():
try:
result = 1 / 0
except Exception:
print("完整错误信息:")
traceback.print_exc()
print("\n错误追踪:")
traceback.print_stack()
buggy_function()
预防错误的编程习惯
输入验证
def validate_age(age):
"""
验证年龄输入
"""
if not isinstance(age, int):
raise TypeError("年龄必须是整数")
if age < 0 or age > 150:
raise ValueError("年龄必须在0-150之间")
return age
# 使用
try:
age = validate_age("25") # 会抛出TypeError
except TypeError as e:
print(f"类型错误:{e}")
使用类型提示
from typing import Union, Optional
def calculate_discount(
price: float,
discount: Union[float, None] = None
) -> float:
"""
计算折扣价格
"""
if discount is None:
discount = 0.1 # 默认10%折扣
if not 0 <= discount <= 1:
raise ValueError("折扣必须在0-1之间")
return price * (1 - discount)
# 使用类型检查工具:mypy
# pip install mypy
# mypy your_script.py
单元测试
import unittest
def add_numbers(a, b):
if not isinstance(a, (int, float)):
raise TypeError("参数必须是数字")
if not isinstance(b, (int, float)):
raise TypeError("参数必须是数字")
return a + b
class TestAddNumbers(unittest.TestCase):
def test_add_positive_numbers(self):
self.assertEqual(add_numbers(5, 3), 8)
def test_add_negative_numbers(self):
self.assertEqual(add_numbers(-5, -3), -8)
def test_add_float_numbers(self):
self.assertEqual(add_numbers(5.5, 3.3), 8.8)
def test_invalid_input(self):
with self.assertRaises(TypeError):
add_numbers("5", 3)
# 运行测试
# unittest.main()
实战修复示例
完整案例:数据处理函数修复
def process_user_data(data):
"""
处理用户数据
"""
# 原始错误代码
# return {
# "name": data["name"].upper(),
# "age": data["age"] + 1,
# "email": data["email"].lower()
# }
# 修复版本
results = []
for item in data:
try:
# 使用get方法安全获取数据
name = item.get("name", "未知用户")
age = item.get("age", 0)
email = item.get("email", "unknown@example.com")
# 类型转换和验证
age = int(age) if age is not None else 0
# 安全处理
processed = {
"name": str(name).upper() if name else "未知用户",
"age": age + 1,
"email": str(email).lower() if email else "未知邮箱"
}
results.append(processed)
except (TypeError, ValueError) as e:
print(f"处理数据时出错:{e}")
results.append({
"name": "处理失败",
"age": 0,
"email": "error@example.com"
})
return results
# 测试数据
test_data = [
{"name": "Alice", "age": 30, "email": "ALICE@EXAMPLE.COM"},
{"name": "Bob", "age": 25, "email": "BOB@EXAMPLE.COM"},
{"name": None, "age": "abc", "email": 123}, # 异常数据
{}, # 空数据
]
# 处理数据
result = process_user_data(test_data)
for item in result:
print(item)
修复Python代码报错的关键步骤:
- 读懂错误信息:确定错误类型和位置
- 分析原因:理解为什么出错
- 选择合适的修复方法:异常处理、类型检查、数据验证等
- 测试修复:确保修改正确
- 预防未来错误:添加适当的验证和错误处理
好的错误处理不仅修复当前问题,还能防止类似问题再次发生。