飞翔飞翔
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
主页
  • 计算机基础

    • TCP/IP协议
    • Linux命令
  • 数据库

    • SQL教程
  • 编程语言

    • C语言
    • Python2
    • Python3
  • 数据格式

    • JSON教程
  • 工具

    • Markdown指南
  • Git

    • GitFlow
  • Quartz

    • Quartz教程
  • Java

    • Java设计模式
  • 缓存

    • Redis教程
联系
阿里云
  • 学习路径
  • 第1章 认识Python

    • Python 历史与特点
    • Python 2 与 Python 3 的核心差异
    • 安装与运行 Python 2.7.18
    • 编码规范 PEP 8
  • 第2章 基础语法

    • 变量与对象
    • 数字类型
    • 字符串 str
    • Unicode 字符串
    • 运算符
    • 空值 None
  • 第3章 流程控制

    • if 条件语句
    • if-else 条件语句
    • if-elif-else 多分支
    • 条件表达式(三元运算符)
    • while 循环
    • for 循环
    • range 与 xrange
    • 循环控制:break、continue、pass
    • 循环 else 子句
  • 第4章 数据结构

    • 列表基础
    • 列表方法
    • 列表推导式
    • 元组
    • 字典基础
    • 字典方法
    • 字典循环技巧
    • 集合
    • 序列解包
    • 序列比较
  • 第5章 函数

    • 定义函数
    • 参数传递机制
    • 默认参数
    • 关键字参数
    • 可变参数
    • Lambda 表达式
    • 文档字符串
    • 函数对象
  • 第6章 模块与包

    • import 导入
    • 模块搜索路径
    • name 与主程序
    • 编译文件 .pyc 与 .pyo
    • 包结构
    • dir() 函数
  • 第7章 文件与IO

    • 打开与关闭文件
    • 文件读写方法
    • with 上下文管理器
    • 格式化输出:% 操作符
    • 格式化输出:str.format()
    • JSON 序列化
  • 第8章 面向对象

    • 类定义与实例化
    • init 构造方法
    • 类变量与实例变量
    • 方法调用与 self
    • 继承基础
    • 多重继承
    • 新式类与旧式类
    • 私有变量与名称改写
    • 属性装饰器 property
    • 类方法与静态方法
    • 魔术方法
    • 空类与数据记录
  • 第9章 异常处理

    • 异常类型
    • try-except
    • try-except-else-finally
    • 抛出异常 raise
    • 自定义异常
    • with 语句与上下文管理器
  • 第10章 迭代器与生成器

    • 迭代器协议
    • 生成器函数
    • 生成器表达式
    • itertools模块
  • 第11章 标准库精要

    • os模块
    • sys模块
    • datetime模块
    • re模块
    • json模块
    • collections模块
    • math与random模块
    • urllib2与网络请求
    • subprocess与命令执行
    • threading与并发
    • unittest与测试
    • 虚拟环境与包管理
  • 第12章 工程实践

    • 调试技巧
    • 性能分析
    • 文档与注释
    • 下一步学习

调试技巧

调试是编程的核心技能。Python 2.7 提供了多种调试工具,从简单的 print 语句到交互式调试器 pdb,再到日志模块 logging。掌握这些工具能大幅缩短定位问题的时间。

print 调试法

最简单直接的调试方式:

def calculate(x, y):
    print "DEBUG: x =", x, "y =", y
    result = x / y
    print "DEBUG: result =", result
    return result

calculate(10, 2)
# DEBUG: x = 10 y = 2
# DEBUG: result = 5

格式化输出:

print "DEBUG: value = %r" % value       # %r 显示 repr,适合字符串
print "DEBUG: locals() =", locals()       # 打印所有局部变量

%r 使用 repr() 格式化,能显示字符串的引号和转义字符,比 %s 更适合调试。

assert 断言

assert 在条件为假时抛出 AssertionError,适合检查"不可能发生"的情况:

def divide(a, b):
    assert b != 0, "Divisor cannot be zero"
    return a / b

divide(10, 0)       # AssertionError: Divisor cannot be zero

注意:assert 可以用 python -O 禁用,不要用它验证用户输入。

pdb 交互式调试器

在代码中插入断点:

import pdb

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

process_data([1, 2, 3])

运行后进入 pdb 交互模式:

> script.py(7)process_data()
-> processed = item * 2
(Pdb)

常用 pdb 命令:

命令简写作用
nextn执行下一行(不进入函数)
steps进入函数调用
continuec继续执行到下一个断点
breakb设置断点
printp打印变量值
listl显示当前代码上下文
wherew显示调用栈
upu移动到上一层调用栈
downd移动到下一层调用栈
quitq退出调试器
(Pdb) p item          # 打印 item 的值
(Pdb) p locals()      # 打印所有局部变量
(Pdb) l               # 显示当前代码
(Pdb) n               # 执行下一行
(Pdb) s               # 进入函数
(Pdb) c               # 继续执行

命令行启动 pdb:

python -m pdb script.py         # 从头开始调试
python -m pdb -c continue script.py   # 先运行,遇到异常暂停

事后调试:

import pdb
import sys

def exception_handler(exc_type, exc_value, exc_traceback):
    print "Exception occurred:"
    pdb.post_mortem(exc_traceback)

sys.excepthook = exception_handler

# 现在任何未捕获的异常都会进入 pdb
1 / 0

日志模块 logging

print 适合临时调试,logging 适合长期维护:

import logging

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

logger = logging.getLogger('myapp')

logger.debug('Debug message')
logger.info('Info message')
logger.warning('Warning message')
logger.error('Error message')
logger.critical('Critical message')

日志级别:

级别数值用途
DEBUG10详细调试信息
INFO20正常运行信息
WARNING30警告,但程序继续
ERROR40错误,部分功能失败
CRITICAL50严重错误,程序可能终止

条件日志:

# 只在调试时输出大量信息
if logger.isEnabledFor(logging.DEBUG):
    logger.debug("Complex data: %s", expensive_operation())

多处理器:

import logging

logger = logging.getLogger('myapp')
logger.setLevel(logging.DEBUG)

# 文件处理器
file_handler = logging.FileHandler('app.log')
file_handler.setLevel(logging.WARNING)

# 控制台处理器
console_handler = logging.StreamHandler()
console_handler.setLevel(logging.DEBUG)

# 格式化
formatter = logging.Formatter('%(asctime)s - %(levelname)s - %(message)s')
file_handler.setFormatter(formatter)
console_handler.setFormatter(formatter)

logger.addHandler(file_handler)
logger.addHandler(console_handler)

# DEBUG 输出到控制台,WARNING 以上输出到文件
logger.debug("Debug info")      # 只在控制台
logger.error("Error info")      # 控制台和文件都有

实际调试场景

追踪变量变化:

class TracedDict(dict):
    def __setitem__(self, key, value):
        import traceback
        print "Setting %s = %r" % (key, value)
        traceback.print_stack(limit=3)
        super(TracedDict, self).__setitem__(key, value)

d = TracedDict()
d['x'] = 1          # 打印设置位置和调用栈

性能问题定位:

import time

def timed(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        elapsed = time.time() - start
        print "%s took %.3f seconds" % (func.__name__, elapsed)
        return result
    return wrapper

@timed
def slow_function():
    time.sleep(1)

slow_function()     # slow_function took 1.002 seconds

异常追踪:

import traceback

try:
    risky_operation()
except Exception:
    # 打印完整异常信息到日志
    logging.error("Operation failed:\n%s", traceback.format_exc())

调试技巧总结

场景推荐工具
快速查看变量print
交互式逐步执行pdb
生产环境问题logging
检查不可能的情况assert
复杂状态追踪自定义类 + traceback
性能问题time / timeit / cProfile

调试的核心是缩小问题范围:先确定问题出现的代码区域,再逐步细化到具体行和变量。

下一页
性能分析