跳到主要内容

调试与问题排查

高效定位和解决程序问题

调试思维

调试流程
├── 1. 复现问题
├── 2. 定位范围
├── 3. 分析原因
├── 4. 验证假设
├── 5. 修复问题
└── 6. 验证修复

Print调试法

# 基础打印
def calculate(a, b):
print(f"输入: a={a}, b={b}") # 查看输入
result = a * b + 10
print(f"计算结果: {result}") # 查看中间值
return result

# 条件打印
DEBUG = True

def debug_print(*args, **kwargs):
if DEBUG:
print("[DEBUG]", *args, **kwargs)

debug_print("这条只在调试模式显示")

# 打印调用栈
import traceback

def problematic_function():
traceback.print_stack() # 打印当前调用栈

# 打印变量类型和值
def inspect_variable(name, value):
print(f"{name}: type={type(value).__name__}, value={value!r}")

inspect_variable("data", {"key": [1, 2, 3]})
# 输出: data: type=dict, value={'key': [1, 2, 3]}

Python调试器 (pdb)

import pdb

def complex_function(data):
result = []
for item in data:
pdb.set_trace() # 程序会在这里暂停
processed = item * 2
result.append(processed)
return result

# pdb常用命令
# n (next) - 执行下一行
# s (step) - 进入函数
# c (continue) - 继续执行
# p variable - 打印变量
# l (list) - 显示当前代码
# q (quit) - 退出调试
# b line_num - 设置断点
# w (where) - 显示调用栈

# 更好的调试器: ipdb
# pip install ipdb
import ipdb
ipdb.set_trace()

# 或使用breakpoint()(Python 3.7+)
def my_function():
x = 10
breakpoint() # 自动进入调试器
return x * 2

VS Code调试

// .vscode/launch.json
{
"version": "0.2.0",
"configurations": [
{
"name": "Python: 当前文件",
"type": "debugpy",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Python: Flask",
"type": "debugpy",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py",
"FLASK_DEBUG": "1"
},
"args": ["run", "--no-debugger"]
}
]
}
VS Code调试快捷键
├── F5 - 开始/继续调试
├── F9 - 切换断点
├── F10 - 单步跳过
├── F11 - 单步进入
├── Shift+F11 - 单步跳出
└── Shift+F5 - 停止调试

日志调试

import logging

# 配置日志
logging.basicConfig(
level=logging.DEBUG,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('app.log'),
logging.StreamHandler()
]
)

logger = logging.getLogger(__name__)

def process_order(order_id):
logger.info(f"开始处理订单: {order_id}")

try:
order = get_order(order_id)
logger.debug(f"订单详情: {order}")

if not order:
logger.warning(f"订单不存在: {order_id}")
return None

result = calculate_total(order)
logger.info(f"订单 {order_id} 处理完成, 总额: {result}")
return result

except Exception as e:
logger.error(f"处理订单失败: {order_id}", exc_info=True)
raise

# 日志级别
# DEBUG - 详细信息,诊断问题
# INFO - 确认程序按预期工作
# WARNING - 表示可能出现问题
# ERROR - 由于严重问题,功能无法执行
# CRITICAL - 严重错误,程序可能无法继续

常见错误类型

语法错误

# SyntaxError: 语法错误
# 检查括号、引号、缩进是否匹配

# 错误
if x == 1
print("hello")

# 正确
if x == 1:
print("hello")

类型错误

# TypeError: 类型不匹配

# 错误
"hello" + 123

# 正确
"hello" + str(123)

# 调试技巧:检查变量类型
print(type(variable))

索引错误

# IndexError: 索引越界

lst = [1, 2, 3]
# lst[3] # IndexError

# 安全访问
if len(lst) > 3:
print(lst[3])

# 或使用异常处理
try:
value = lst[3]
except IndexError:
value = None

键错误

# KeyError: 字典键不存在

data = {"name": "张三"}
# data["age"] # KeyError

# 安全方式1: get方法
age = data.get("age", 0)

# 安全方式2: 检查键
if "age" in data:
age = data["age"]

属性错误

# AttributeError: 对象没有该属性

# 检查属性是否存在
if hasattr(obj, "method"):
obj.method()

# 使用getattr提供默认值
value = getattr(obj, "attr", "default")

性能调试

import time
import cProfile

# 简单计时
start = time.time()
result = slow_function()
end = time.time()
print(f"耗时: {end - start:.4f}秒")

# 装饰器计时
def timer(func):
def wrapper(*args, **kwargs):
start = time.time()
result = func(*args, **kwargs)
end = time.time()
print(f"{func.__name__} 耗时: {end - start:.4f}秒")
return result
return wrapper

@timer
def my_function():
# 执行操作
pass

# 性能分析
cProfile.run('my_function()')

# 或保存到文件
cProfile.run('my_function()', 'profile_result')

# 内存分析
# pip install memory_profiler
from memory_profiler import profile

@profile
def memory_heavy_function():
big_list = [i for i in range(1000000)]
return sum(big_list)

调试清单

## 问题排查清单

### 基础检查
- [ ] 错误信息完整阅读了吗?
- [ ] 最近改动了什么代码?
- [ ] 问题能稳定复现吗?

### 数据检查
- [ ] 输入数据是否正确?
- [ ] 数据类型是否匹配?
- [ ] 边界值是否处理?

### 环境检查
- [ ] 依赖版本是否正确?
- [ ] 配置是否正确?
- [ ] 环境变量是否设置?

### 逻辑检查
- [ ] 条件判断是否正确?
- [ ] 循环是否正确终止?
- [ ] 异常是否正确处理?

本章小结

  • Print调试:简单快速的入门方法
  • 调试器:pdb/IDE调试器深入排查
  • 日志:生产环境问题追踪
  • 系统方法:复现→定位→修复→验证

→ 继续阅读:45-高效学习方法