Python断点调试案例实操?

wen python案例 2

本文目录导读:

  1. 基础断点调试案例
  2. 使用pdb进行调试
  3. 使用IPython的%debug魔法命令
  4. 使用VSCode/PyCharm图形化断点
  5. 高级调试技巧实例
  6. 调试实战技巧
  7. 使用建议

我来给你演示几个Python断点调试的实战案例,从基础到进阶:

基础断点调试案例

# debug_demo1.py
def calculate_average(numbers):
    """计算平均值"""
    total = 0
    count = 0
    for num in numbers:
        total += num
        count += 1
        print(f"当前总数: {total}, 当前计数: {count}")  # 这里可以设置断点
    average = total / count
    return average
def complex_calculation(x, y):
    """复杂计算"""
    result1 = x ** 2 + y ** 2
    result2 = (x + y) * (x - y)
    final_result = result1 / result2 if result2 != 0 else 0
    # 这里可以设置条件断点,比如当 final_result > 10 时暂停
    if final_result > 10:
        print("结果大于10!")
    return final_result
# 主程序
if __name__ == "__main__":
    # 测试数据
    data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    # 设置断点观察执行流程
    avg = calculate_average(data)
    print(f"平均值: {avg}")
    # 复杂计算
    result = complex_calculation(5, 3)
    print(f"复杂计算结果: {result}")

使用pdb进行调试

# pdb_debug.py
import pdb
def factorial(n):
    """计算阶乘"""
    if n < 0:
        return None
    if n == 0 or n == 1:
        return 1
    result = 1
    for i in range(1, n + 1):
        result *= i
        # 设置断点,观察中间值
        # pdb.set_trace()  # 取消注释启用pdb
    return result
def process_data(items):
    """处理数据列表"""
    processed = []
    for index, item in enumerate(items):
        try:
            # 模拟可能出错的场景
            value = float(item)
            if value > 100:
                pdb.set_trace()  # 当值大于100时进入调试模式
            processed.append({
                'index': index,
                'original': item,
                'value': value,
                'squared': value ** 2
            })
        except (ValueError, TypeError) as e:
            print(f"处理项 {item} 时出错: {e}")
            continue
    return processed
# 使用示例
if __name__ == "__main__":
    # 测试阶乘
    print(f"5! = {factorial(5)}")  # 可以在此设置断点
    # 测试数据处理
    mixed_data = ['10', '20', 'abc', '150', '30.5', '-5']
    results = process_data(mixed_data)
    print("处理结果:")
    for r in results:
        print(f"索引 {r['index']}: 原始值={r['original']}, 值={r['value']}, 平方={r['squared']}")

使用IPython的%debug魔法命令

# ipython_debug_demo.py
def buggy_function():
    """含有bug的函数示例"""
    data = [1, 2, 3, 4, 5]
    result = []
    for i in range(len(data) + 1):  # 故意越界
        try:
            value = data[i] * 2
            result.append(value / (i - 2))  # 当i=2时会除以0
        except Exception as e:
            print(f"错误: {e}")
            # 这里可以插入pdb.set_trace()进行调试
            raise
    return result
def analyze_data(data):
    """数据分析函数"""
    if len(data) == 0:
        return None
    total = sum(data)
    mean = total / len(data)
    # 计算方差
    variance = sum((x - mean) ** 2 for x in data) / len(data)
    std_dev = variance ** 0.5
    # 计算异常值
    threshold = 2 * std_dev
    outliers = [x for x in data if abs(x - mean) > threshold]
    return {
        'mean': mean,
        'std_dev': std_dev,
        'outliers': outliers,
        'data_range': (min(data), max(data))
    }
# 使用IPython的%debug调试
if __name__ == "__main__":
    # 在IPython环境中可以这样使用:
    # %run ipython_debug_demo.py
    # 遇到错误后输入 %debug 进入调试模式
    try:
        # 测试分析函数
        test_data = [10, 12, 11, 13, 9, 100, 11, 12, 10, 11]
        analysis = analyze_data(test_data)
        print(f"分析结果: {analysis}")
        # 触发bug
        result = buggy_function()
        print(result)
    except Exception as e:
        print(f"发生错误: {e}")
        print("在IPython中可输入 %debug 进行调试")

使用VSCode/PyCharm图形化断点

# ide_debug_demo.py
class DataProcessor:
    """数据处理类,适合IDE断点调试"""
    def __init__(self, data):
        self.data = data
        self.processed_data = []
        self.statistics = {}
    def validate_data(self):
        """数据验证"""
        valid_data = []
        for item in self.data:
            try:
                if isinstance(item, (int, float)):
                    if 0 <= item <= 100:  # 可以在这里设置条件断点
                        valid_data.append(item)
                    else:
                        print(f"数据 {item} 超出范围")
                else:
                    print(f"数据 {item} 类型错误")
            except Exception as e:
                print(f"验证错误: {e}")
        return valid_data
    def transform_data(self, data):
        """数据转换"""
        transformed = []
        for value in data:
            # 可以在这里设置条件断点,value > 50
            new_value = value * 1.5 + 10
            transformed.append(new_value)
        return transformed
    def analyze_data(self, data):
        """数据分析"""
        if not data:
            return {}
        analysis = {
            'count': len(data),
            'sum': sum(data),
            'mean': sum(data) / len(data) if data else 0,
            'max': max(data),
            'min': min(data)
        }
        # 计算百分位数
        sorted_data = sorted(data)
        n = len(sorted_data)
        analysis['p50'] = sorted_data[n // 2]  # 中位数
        analysis['p90'] = sorted_data[int(n * 0.9)]  # 90百分位
        return analysis
    def process(self):
        """主处理流程"""
        print("开始数据处理...")
        # 在IDE中可以在此处设置断点,逐行查看执行过程
        valid_data = self.validate_data()
        print(f"验证后的数据: {valid_data}")
        transformed_data = self.transform_data(valid_data)
        print(f"转换后的数据: {transformed_data}")
        analysis = self.analyze_data(transformed_data)
        print(f"分析结果: {analysis}")
        self.processed_data = transformed_data
        self.statistics = analysis
        return transformed_data, analysis
# 调试主程序
if __name__ == "__main__":
    # 创建测试数据
    test_data = [10, 20, 30, 40, 50, 60, 70, 80, 90, 100, -5, 105, 'abc']
    # 实例化处理器
    processor = DataProcessor(test_data)
    # 在IDE中在此处设置断点,逐行调试
    processed_data, stats = processor.process()
    print("\n最终结果:")
    print(f"处理后的数据: {processed_data}")
    print(f"统计数据: {stats}")

高级调试技巧实例

# advanced_debug.py
import logging
from functools import wraps
# 设置日志记录
logging.basicConfig(level=logging.DEBUG, 
                   format='%(asctime)s - %(levelname)s - %(message)s')
def debug_decorator(func):
    """调试装饰器"""
    @wraps(func)
    def wrapper(*args, **kwargs):
        logging.debug(f"调用函数: {func.__name__}")
        logging.debug(f"位置参数: {args}")
        logging.debug(f"关键字参数: {kwargs}")
        try:
            result = func(*args, **kwargs)
            logging.debug(f"函数返回: {result}")
            return result
        except Exception as e:
            logging.error(f"函数出错: {e}")
            raise
    return wrapper
@debug_decorator
def complex_algorithm(data, threshold=0.5):
    """复杂算法示例"""
    result = []
    for i, value in enumerate(data):
        # 可以在这里设置条件断点
        if value > threshold:
            transformed = value * (i + 1) ** 2
            result.append({
                'index': i,
                'original': value,
                'transformed': transformed,
                'threshold': threshold
            })
            # 当transformed超过一定值时,记录日志
            if transformed > 100:
                logging.warning(f"值过大: index={i}, transformed={transformed}")
    return result
def recursive_debug(n, depth=0):
    """递归函数调试示例"""
    indent = "  " * depth
    logging.debug(f"{indent}进入递归: n={n}, depth={depth}")
    # 基本条件
    if n <= 1:
        logging.debug(f"{indent}基本条件满足,返回 1")
        return 1
    # 递归调用
    result = n * recursive_debug(n - 1, depth + 1)
    logging.debug(f"{indent}递归返回: n={n}, result={result}")
    return result
# 主程序
if __name__ == "__main__":
    # 测试复杂算法
    test_data = [0.1, 0.6, 0.3, 0.8, 0.2, 0.9]
    results = complex_algorithm(test_data, 0.5)
    print("\n算法结果:")
    for r in results:
        print(f"索引 {r['index']}: 原始值={r['original']}, "
              f"转换值={r['transformed']}, 阈值={r['threshold']}")
    print("\n" + "="*50)
    # 测试递归函数
    n = 5
    factorial = recursive_debug(n)
    print(f"\n{n}! = {factorial}")

调试实战技巧

# debug_tips.py
def debug_tips_demo():
    """断点调试实用技巧"""
    # 1. 条件断点示例
    numbers = list(range(20))
    for i, num in enumerate(numbers):
        # 仅在 num % 3 == 0 时暂停
        if num % 3 == 0:  # 在IDE中对此行设置条件断点: num % 3 == 0
            print(f"找到3的倍数: {num}")
    # 2. 观察点(Watch)示例
    data_stream = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
    running_total = 0
    for value in data_stream:
        running_total += value
        # 观察 running_total 的变化
        # 当 running_total > 30 时设置条件断点
        if running_total > 30:  # 条件断点位置
            print(f"总和超过30: {running_total}")
    # 3. 多线程调试
    import threading
    import time
    def worker(name, delay):
        for i in range(5):
            time.sleep(delay)
            print(f"{name}: 第{i+1}次执行")
            # 在此设置断点观察线程执行顺序
    threads = []
    for i in range(3):
        t = threading.Thread(target=worker, args=(f"线程{i}", 0.1 * (i+1)))
        threads.append(t)
        t.start()
    for t in threads:
        t.join()
    # 4. 异常断点
    def risky_operation():
        """可能抛出多种异常的操作"""
        try:
            # 故意制造不同类型错误
            x = 1 / 0  # ZeroDivisionError
        except ZeroDivisionError:
            print("除以零错误")
        try:
            y = int("abc")  # ValueError
        except ValueError:
            print("类型转换错误")
        try:
            z = [1, 2, 3][10]  # IndexError
        except IndexError:
            print("索引越界错误")
# 运行演示
if __name__ == "__main__":
    print("=== 断点调试技巧演示 ===")
    debug_tips_demo()
    print("\n=== 危险操作演示 ===")
    risky_operation()

使用建议

  1. 选择合适的调试工具

    • 简单调试:使用 print() 语句
    • 复杂调试:使用 IDE 图形化断点(VSCode/PyCharm)
    • 高级调试:使用 pdb/ipdb 命令行工具
  2. 断点类型

    • 普通断点:在任何行设置
    • 条件断点:满足特定条件时才暂停
    • 异常断点:当抛出异常时暂停
    • 日志断点:记录信息但不暂停
  3. 调试技巧

    • 使用 Watch 观察特定变量
    • 使用 Call Stack 查看函数调用链
    • 使用 Step Over/Into/Out 控制执行流程
    • 使用 Evaluate Expression 执行临时代码

这些案例涵盖了Python断点调试的主要场景和技巧,你可以根据自己的需要选择合适的方式进行调试。

标签: 案例实操

抱歉,评论功能暂时关闭!