目录

告别Print-Python调试入门,用PDB高效找Bug

告别Print: Python调试入门,用PDB高效找Bug

『宝藏代码胶囊开张啦!』—— 我的 CodeCapsule 来咯!✨
写代码不再头疼!我的新站点 CodeCapsule 主打一个 “白菜价”+“量身定制”!无论是卡脖子的毕设/课设/文献复现,需要灵光一现的算法改进,还是想给项目加个“外挂”,这里都有便宜又好用的代码方案等你发现!低成本,高适配,助你轻松通关!速来围观 👉

告别Print: Python调试入门,用PDB高效找Bug

1. 为什么需要专业的调试工具

1.1 Print调试的局限性

在Python开发过程中,很多开发者习惯使用print()语句进行调试,这种方法虽然简单直接,但存在诸多局限性:

# 典型的print调试示例
def calculate_stats(data):
    print(f"输入数据: {data}")  # 调试语句1
    mean = sum(data) / len(data)
    print(f"计算均值: {mean}")  # 调试语句2
    
    variance = sum((x - mean) ** 2 for x in data) / len(data)
    print(f"计算方差: {variance}")  # 调试语句3
    
    std_dev = variance ** 0.5
    print(f"最终结果: {std_dev}")  # 调试语句4
    return std_dev

# 测试代码
data = [1, 2, 3, 4, 5]
result = calculate_stats(data)
print(f"最终输出: {result}")

Print调试的主要问题:

  1. 代码污染:调试语句与业务逻辑混杂
  2. 效率低下:需要频繁添加、删除print语句
  3. 信息有限:只能看到输出值,无法观察程序状态
  4. 难以调试复杂问题:对于循环、递归、异常处理等场景力不从心

1.2 专业调试工具的优势

专业的调试工具如PDB(Python Debugger)提供了以下优势:

  • 断点设置:在特定位置暂停程序执行
  • 变量检查:实时查看和修改变量值
  • 步进执行:逐行或逐函数执行代码
  • 调用栈查看:了解函数调用关系
  • 条件断点:满足特定条件时暂停
  • 事后调试:分析程序崩溃后的状态

2. PDB基础入门

2.1 PDB简介

PDB是Python的标准调试器,无需安装额外包,是Python标准库的一部分。它提供了交互式的调试环境,可以帮助开发者深入理解代码执行过程。

2.2 启动PDB的三种方式

2.2.1 命令行直接启动
# 直接调试Python脚本
python -m pdb script.py

# 示例:调试一个简单的计算器程序
python -m pdb calculator.py
2.2.2 在代码中嵌入断点
# 方法1:使用pdb.set_trace()
import pdb

def faulty_function(x, y):
    result = x + y
    pdb.set_trace()  # 在此处进入调试器
    result *= 2
    return result

# 方法2:Python 3.7+ 使用breakpoint()
def modern_function(x, y):
    result = x + y
    breakpoint()  # 等同于pdb.set_trace(),但更现代
    result *= 2
    return result
2.2.3 事后调试
import pdb
import traceback

def problematic_function():
    try:
        # 可能出错的代码
        x = 1 / 0
    except Exception as e:
        print("发生异常,进入调试模式:")
        traceback.print_exc()
        pdb.post_mortem()  # 事后调试,检查异常发生时的状态

problematic_function()

3. PDB核心命令详解

3.1 基本调试命令

# 演示用的示例代码:complex_calculation.py
def factorial(n):
    """计算阶乘"""
    if n <= 1:
        return 1
    else:
        return n * factorial(n - 1)

def calculate_combinations(n, k):
    """计算组合数C(n, k)"""
    # 设置断点
    import pdb; pdb.set_trace()
    
    if k < 0 or k > n:
        return 0
    
    numerator = factorial(n)
    denominator = factorial(k) * factorial(n - k)
    
    result = numerator // denominator
    return result

# 测试
if __name__ == "__main__":
    print("计算C(5, 2):")
    result = calculate_combinations(5, 2)
    print(f"结果: {result}")

常用PDB命令表:

命令缩写功能描述
helph查看帮助信息
nextn执行下一行
steps进入函数调用
continuec继续执行直到下一个断点
printp打印变量值
listl显示当前代码位置
returnr执行直到当前函数返回
wherew显示调用栈
quitq退出调试器

3.2 高级调试技巧

3.2.1 条件断点
def process_data(data_list):
    """处理数据列表,在特定条件下设置断点"""
    results = []
    
    for i, item in enumerate(data_list):
        # 条件断点:当i等于3时暂停
        if i == 3:
            import pdb; pdb.set_trace()
        
        # 处理数据
        processed = item * 2 + 10
        
        # 另一个条件:当处理结果大于50时暂停
        if processed > 50:
            import pdb; pdb.set_trace()
            
        results.append(processed)
    
    return results

# 更优雅的条件断点设置
def smart_breakpoint(condition, *args):
    """智能断点函数"""
    if condition:
        breakpoint()

def improved_processor(data_list):
    results = []
    for i, item in enumerate(data_list):
        # 使用智能断点
        smart_breakpoint(i == 2, f"索引i={i}")
        smart_breakpoint(item > 100, f"数据项={item}")
        
        results.append(item ** 2)
    return results
3.2.2 观察点(Watchpoint)
class DataProcessor:
    def __init__(self):
        self.counter = 0
        self.data = []
    
    def add_data(self, value):
        """添加数据并计数"""
        self.data.append(value)
        self.counter += 1
        
        # 当counter达到特定值时调试
        if self.counter == 5:
            breakpoint()  # 观察计数器变化
    
    def process(self):
        """处理数据"""
        total = sum(self.data)
        
        # 观察总和变化
        if total > 100:
            breakpoint()
            
        return total

# 使用示例
processor = DataProcessor()
for i in range(10):
    processor.add_data(i * 10)
result = processor.process()

4. 实战:调试复杂程序

4.1 调试递归函数

# recursive_debug.py
def fibonacci(n, depth=0):
    """计算斐波那契数列(带调试信息)"""
    indent = "  " * depth
    print(f"{indent}fibonacci({n})被调用")
    
    # 设置条件断点:在特定深度或数值时暂停
    if depth == 3 or n == 2:
        breakpoint()
    
    if n <= 1:
        print(f"{indent}返回: {n}")
        return n
    else:
        result = fibonacci(n-1, depth+1) + fibonacci(n-2, depth+1)
        print(f"{indent}返回: {result}")
        return result

def debug_fibonacci():
    """专门用于调试的包装函数"""
    print("开始计算斐波那契数列:")
    result = fibonacci(5)
    print(f"最终结果: {result}")
    return result

if __name__ == "__main__":
    debug_fibonacci()

4.2 调试面向对象程序

# oop_debug.py
class BankAccount:
    def __init__(self, account_holder, initial_balance=0):
        self.account_holder = account_holder
        self._balance = initial_balance
        self.transaction_history = []
        print(f"账户创建: {account_holder}, 初始余额: {initial_balance}")
    
    def deposit(self, amount):
        """存款"""
        if amount <= 0:
            raise ValueError("存款金额必须大于0")
        
        self._balance += amount
        self.transaction_history.append(('deposit', amount))
        
        # 调试点:大额存款时暂停
        if amount > 1000:
            breakpoint()
        
        print(f"存款: {amount}, 新余额: {self._balance}")
        return self._balance
    
    def withdraw(self, amount):
        """取款"""
        if amount <= 0:
            raise ValueError("取款金额必须大于0")
        if amount > self._balance:
            raise ValueError("余额不足")
        
        self._balance -= amount
        self.transaction_history.append(('withdraw', amount))
        
        # 调试点:余额低于阈值时暂停
        if self._balance < 100:
            breakpoint()
        
        print(f"取款: {amount}, 新余额: {self._balance}")
        return self._balance
    
    def transfer(self, amount, target_account):
        """转账"""
        print(f"开始转账: {amount}{target_account.account_holder}")
        
        # 调试点:转账操作
        breakpoint()
        
        self.withdraw(amount)
        target_account.deposit(amount)
        self.transaction_history.append(('transfer', amount, target_account.account_holder))
        
        print("转账完成")
    
    @property
    def balance(self):
        return self._balance

def test_bank_account():
    """测试银行账户功能"""
    # 创建账户
    alice = BankAccount("Alice", 1000)
    bob = BankAccount("Bob", 500)
    
    # 执行操作
    alice.deposit(200)
    alice.withdraw(100)
    alice.transfer(300, bob)
    
    # 检查最终状态
    print(f"Alice余额: {alice.balance}")
    print(f"Bob余额: {bob.balance}")
    print(f"Alice交易记录: {alice.transaction_history}")

if __name__ == "__main__":
    test_bank_account()

5. 高级PDB技巧

5.1 PDB配置与自定义

# .pdbrc.py - PDB启动配置文件
import pdb

def setup_pdb():
    """PDB配置函数"""
    # 自定义显示格式
    pdb.DefaultConfig.stdin = sys.stdin
    pdb.DefaultConfig.stdout = sys.stdout
    pdb.DefaultConfig.use_terminal = True
    
    # 自定义提示符
    pdb.DefaultConfig.prompt = "(我的调试器) "
    
    # 自动导入常用模块
    import os
    import sys
    
    print("PDB调试环境已初始化")

# 常用的调试辅助函数
def debug_vars(local_vars):
    """调试变量显示函数"""
    print("=== 变量状态 ===")
    for name, value in local_vars.items():
        if not name.startswith('_'):
            print(f"{name}: {value}")

def whereami():
    """显示当前位置"""
    import inspect
    frame = inspect.currentframe().f_back
    print(f"文件: {frame.f_code.co_filename}")
    print(f"行号: {frame.f_lineno}")
    print(f"函数: {frame.f_code.co_name}")

# 在PDB中使用的便捷命令
class DebugCommands:
    @staticmethod
    def show_locals():
        """显示所有局部变量"""
        import inspect
        frame = inspect.currentframe().f_back.f_back
        locals_dict = frame.f_locals
        debug_vars(locals_dict)
    
    @staticmethod
    def show_globals():
        """显示所有全局变量"""
        import inspect
        frame = inspect.currentframe().f_back.f_back
        globals_dict = frame.f_globals
        debug_vars(globals_dict)

5.2 远程调试

# remote_debug.py
import pdb
import socket
import threading

class RemoteDebugger:
    """远程调试器类"""
    
    def __init__(self, host='localhost', port=4444):
        self.host = host
        self.port = port
        self.debugger = None
    
    def start_remote_debug(self):
        """启动远程调试服务"""
        def debug_server():
            # 创建socket服务器
            server = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
            server.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
            server.bind((self.host, self.port))
            server.listen(1)
            
            print(f"远程调试服务启动在 {self.host}:{self.port}")
            print("等待调试客户端连接...")
            
            client, addr = server.accept()
            print(f"调试客户端已连接: {addr}")
            
            # 重定向输入输出到socket
            sys.stdin = client.makefile('r')
            sys.stdout = client.makefile('w')
            sys.stderr = client.makefile('w')
            
            # 启动PDB
            self.debugger = pdb.Pdb(stdin=sys.stdin, stdout=sys.stdout)
            self.debugger.set_trace()
        
        # 在新线程中运行调试服务器
        debug_thread = threading.Thread(target=debug_server)
        debug_thread.daemon = True
        debug_thread.start()
    
    def set_breakpoint(self, frame=None):
        """设置远程断点"""
        if self.debugger:
            self.debugger.set_trace(frame)

# 使用示例
def complex_algorithm(data):
    """复杂的算法函数"""
    results = []
    
    # 设置远程调试断点
    debugger = RemoteDebugger()
    debugger.start_remote_debug()
    
    for i, item in enumerate(data):
        # 业务逻辑
        processed = item ** 2 + item * 2 + 1
        
        # 在特定条件下触发远程调试
        if processed > 1000:
            debugger.set_breakpoint()
        
        results.append(processed)
    
    return results

6. PDB与其他工具集成

6.1 与IDE调试器对比

# ide_integration.py
"""
演示如何在不同IDE中使用调试功能
"""

def compare_debugging_methods():
    """比较不同调试方法"""
    methods = {
        "PDB": {
            "优点": ["无需IDE", "服务器环境可用", "灵活性强"],
            "缺点": ["命令行操作", "学习曲线较陡"],
            "适用场景": ["生产环境调试", "远程调试", "简单脚本"]
        },
        "PyCharm调试器": {
            "优点": ["图形化界面", "功能丰富", "易用性好"],
            "缺点": ["需要IDE", "资源占用较多"],
            "适用场景": ["开发环境", "复杂项目", "团队协作"]
        },
        "VSCode调试器": {
            "优点": ["轻量级", "配置灵活", "扩展性强"],
            "缺点": ["需要配置", "功能相对简单"],
            "适用场景": ["跨平台开发", "轻量级项目"]
        }
    }
    
    return methods

def integrated_debugging_example():
    """集成调试示例"""
    data = [1, 2, 3, 4, 5]
    results = []
    
    try:
        for i, item in enumerate(data):
            # 复杂的处理逻辑
            result = item ** 2
            
            # 条件调试:根据不同环境选择调试方法
            if os.getenv('DEBUG_METHOD') == 'PDB':
                import pdb; pdb.set_trace()
            elif os.getenv('DEBUG_METHOD') == 'IDE':
                # 这里可以设置IDE的断点
                pass
            
            results.append(result)
            
    except Exception as e:
        # 异常处理中的调试
        print(f"发生异常: {e}")
        if os.getenv('POST_MORTEM_DEBUG', 'false').lower() == 'true':
            import pdb; pdb.post_mortem()
    
    return results

6.2 与测试框架结合

# test_debug_integration.py
import unittest
import pdb
import sys

class TestDebugIntegration(unittest.TestCase):
    """测试与调试的集成"""
    
    def setUp(self):
        """测试准备"""
        self.test_data = [1, 2, 3, 4, 5]
    
    def debug_test_failure(self, func, *args):
        """调试测试失败的函数"""
        try:
            result = func(*args)
            return result
        except Exception as e:
            print(f"测试失败,进入调试模式: {e}")
            tb = sys.exc_info()[2]
            pdb.post_mortem(tb)
            raise
    
    def test_complex_calculation(self):
        """测试复杂计算"""
        def complex_calc(data):
            results = []
            for item in data:
                # 可能出错的复杂计算
                if item == 0:
                    raise ValueError("遇到零值")
                result = 100 / item + item ** 2
                results.append(result)
            return results
        
        # 使用调试包装器
        result = self.debug_test_failure(complex_calc, self.test_data)
        self.assertEqual(len(result), 5)
    
    def test_with_breakpoint(self):
        """带断点的测试"""
        def problematic_function(x):
            # 设置条件断点
            if x > 10:
                breakpoint()
            return x * 2
        
        # 这个测试会在特定条件下触发调试器
        result = problematic_function(15)
        self.assertEqual(result, 30)

def run_tests_with_debug():
    """带调试的测试运行器"""
    # 创建测试套件
    loader = unittest.TestLoader()
    suite = loader.loadTestsFromTestCase(TestDebugIntegration)
    
    # 运行测试
    runner = unittest.TextTestRunner(verbosity=2)
    
    try:
        result = runner.run(suite)
        return result.wasSuccessful()
    except Exception as e:
        print(f"测试运行异常: {e}")
        return False

if __name__ == "__main__":
    run_tests_with_debug()

7. 完整调试示例项目

# complete_debug_example.py
"""
完整的调试示例:一个数据处理管道
"""

import pdb
import logging
from typing import List, Dict, Any
import json

# 配置日志
logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

class DataProcessingPipeline:
    """数据处理管道类"""
    
    def __init__(self):
        self.stages = []
        self.context = {}
        self.debug_enabled = False
    
    def add_stage(self, stage_func, name=None):
        """添加处理阶段"""
        stage_info = {
            'func': stage_func,
            'name': name or stage_func.__name__
        }
        self.stages.append(stage_info)
        logger.debug(f"添加处理阶段: {stage_info['name']}")
    
    def enable_debug(self, enabled=True):
        """启用调试模式"""
        self.debug_enabled = enabled
        if enabled:
            logger.info("调试模式已启用")
    
    def execute(self, input_data: List[Dict]) -> List[Dict]:
        """执行数据处理管道"""
        logger.info(f"开始处理数据,共{len(input_data)}条记录")
        
        current_data = input_data.copy()
        
        for i, stage in enumerate(self.stages):
            stage_name = stage['name']
            stage_func = stage['func']
            
            logger.info(f"执行阶段 {i+1}/{len(self.stages)}: {stage_name}")
            
            try:
                # 调试点:每个阶段开始前
                if self.debug_enabled:
                    logger.debug(f"阶段开始前调试点")
                    self._debug_checkpoint(f"before_stage_{i}", current_data)
                
                # 执行处理阶段
                current_data = stage_func(current_data, self.context)
                
                # 调试点:每个阶段结束后
                if self.debug_enabled:
                    logger.debug(f"阶段结束后调试点")
                    self._debug_checkpoint(f"after_stage_{i}", current_data)
                
                logger.info(f"阶段完成: {stage_name}")
                
            except Exception as e:
                logger.error(f"阶段执行失败: {stage_name}, 错误: {e}")
                logger.info("进入调试模式...")
                pdb.post_mortem()
                raise
        
        logger.info("数据处理管道执行完成")
        return current_data
    
    def _debug_checkpoint(self, checkpoint_name, data):
        """调试检查点"""
        print(f"\n=== 调试检查点: {checkpoint_name} ===")
        print(f"数据条数: {len(data)}")
        
        if data:
            sample = data[0] if isinstance(data, list) else data
            print(f"数据样本: {json.dumps(sample, indent=2, ensure_ascii=False)}")
        
        # 交互式调试
        if self.debug_enabled:
            response = input("继续执行? (y/n/debug): ").lower()
            if response == 'n':
                raise KeyboardInterrupt("用户中断执行")
            elif response == 'debug':
                breakpoint()

# 具体的处理阶段函数
def stage_clean_data(data, context):
    """数据清洗阶段"""
    logger.debug("开始数据清洗")
    
    cleaned_data = []
    for record in data:
        # 简单的数据清洗
        cleaned_record = {k: v for k, v in record.items() if v is not None}
        
        # 调试点:检查特定条件
        if len(cleaned_record) == 0:
            logger.warning("发现空记录")
            if context.get('debug_empty_records', False):
                breakpoint()
        
        cleaned_data.append(cleaned_record)
    
    return cleaned_data

def stage_calculate_stats(data, context):
    """统计计算阶段"""
    logger.debug("开始统计计算")
    
    if not data:
        return data
    
    # 计算基本统计信息
    numeric_fields = []
    for record in data:
        for key, value in record.items():
            if isinstance(value, (int, float)) and key not in numeric_fields:
                numeric_fields.append(key)
    
    # 为每个数值字段计算统计量
    stats = {}
    for field in numeric_fields:
        values = [record.get(field, 0) for record in data if field in record]
        if values:
            stats[field] = {
                'count': len(values),
                'mean': sum(values) / len(values),
                'min': min(values),
                'max': max(values)
            }
    
    context['statistics'] = stats
    logger.debug(f"计算统计信息: {stats}")
    
    return data

def stage_enrich_data(data, context):
    """数据增强阶段"""
    logger.debug("开始数据增强")
    
    enriched_data = []
    for i, record in enumerate(data):
        # 添加索引信息
        record['_index'] = i
        record['_processed'] = True
        
        # 调试点:处理特定记录时暂停
        if i == len(data) // 2:  # 处理到中间记录时
            logger.debug(f"处理中间记录: {i}")
            if context.get('debug_midpoint', False):
                breakpoint()
        
        enriched_data.append(record)
    
    return enriched_data

def main():
    """主函数:演示完整的数据处理管道"""
    # 创建测试数据
    sample_data = [
        {'name': 'Alice', 'age': 25, 'score': 85.5},
        {'name': 'Bob', 'age': 30, 'score': 92.0},
        {'name': 'Charlie', 'age': None, 'score': 78.5},  # 包含空值
        {'name': 'Diana', 'age': 28, 'score': None},      # 包含空值
        {'name': 'Eve', 'age': 35, 'score': 88.0}
    ]
    
    # 创建处理管道
    pipeline = DataProcessingPipeline()
    pipeline.enable_debug(True)  # 启用调试模式
    
    # 配置调试上下文
    pipeline.context = {
        'debug_empty_records': True,
        'debug_midpoint': True
    }
    
    # 添加处理阶段
    pipeline.add_stage(stage_clean_data, "数据清洗")
    pipeline.add_stage(stage_calculate_stats, "统计计算")
    pipeline.add_stage(stage_enrich_data, "数据增强")
    
    try:
        # 执行管道
        result = pipeline.execute(sample_data)
        
        # 输出结果
        print("\n=== 处理结果 ===")
        for record in result:
            print(json.dumps(record, indent=2, ensure_ascii=False))
        
        print(f"\n=== 统计信息 ===")
        print(json.dumps(pipeline.context['statistics'], indent=2, ensure_ascii=False))
        
    except Exception as e:
        logger.error(f"管道执行失败: {e}")
        print("进入事后调试...")
        pdb.post_mortem()

if __name__ == "__main__":
    main()

8. 调试最佳实践与工作流

8.1 系统化的调试方法

# debugging_workflow.py
"""
系统化的调试工作流实现
"""

class SystematicDebugger:
    """系统化调试器"""
    
    def __init__(self):
        self.breakpoints = {}
        self.watchpoints = {}
        self.history = []
    
    def add_breakpoint(self, condition_func, description=""):
        """添加断点"""
        bp_id = len(self.breakpoints) + 1
        self.breakpoints[bp_id] = {
            'condition': condition_func,
            'description': description,
            'hit_count': 0
        }
        return bp_id
    
    def add_watchpoint(self, variable_name, condition_func, description=""):
        """添加观察点"""
        wp_id = len(self.watchpoints) + 1
        self.watchpoints[wp_id] = {
            'variable': variable_name,
            'condition': condition_func,
            'description': description,
            'hit_count': 0
        }
        return wp_id
    
    def check_breakpoints(self, local_vars, global_vars):
        """检查断点条件"""
        for bp_id, bp_info in self.breakpoints.items():
            try:
                if bp_info['condition'](local_vars, global_vars):
                    bp_info['hit_count'] += 1
                    self.history.append({
                        'type': 'breakpoint',
                        'id': bp_id,
                        'description': bp_info['description'],
                        'timestamp': self._get_timestamp(),
                        'variables': local_vars.copy()
                    })
                    
                    print(f"\n*** 断点命中: {bp_info['description']} ***")
                    print(f"命中次数: {bp_info['hit_count']}")
                    breakpoint()
                    
            except Exception as e:
                print(f"断点检查错误: {e}")
    
    def debug_function(self, func):
        """调试装饰器"""
        def wrapper(*args, **kwargs):
            # 记录函数调用
            call_info = {
                'function': func.__name__,
                'args': args,
                'kwargs': kwargs,
                'timestamp': self._get_timestamp()
            }
            self.history.append(call_info)
            
            # 执行前检查断点
            frame = sys._getframe()
            self.check_breakpoints(frame.f_locals, frame.f_globals)
            
            try:
                result = func(*args, **kwargs)
                return result
            except Exception as e:
                # 异常处理
                error_info = {
                    'function': func.__name__,
                    'exception': str(e),
                    'timestamp': self._get_timestamp()
                }
                self.history.append(error_info)
                print(f"函数 {func.__name__} 执行异常: {e}")
                pdb.post_mortem()
                raise
        
        return wrapper
    
    def _get_timestamp(self):
        """获取时间戳"""
        from datetime import datetime
        return datetime.now().isoformat()
    
    def print_debug_report(self):
        """打印调试报告"""
        print("\n" + "="*50)
        print("调试报告")
        print("="*50)
        
        print(f"\n断点统计:")
        for bp_id, bp_info in self.breakpoints.items():
            print(f"  {bp_id}: {bp_info['description']} - 命中 {bp_info['hit_count']} 次")
        
        print(f"\n调用历史 (最近10次):")
        for i, event in enumerate(self.history[-10:]):
            print(f"  {i+1}. {event}")

# 使用示例
def demo_systematic_debugging():
    """演示系统化调试"""
    debugger = SystematicDebugger()
    
    # 定义断点条件
    def bp_high_value(locals, globals):
        return 'result' in locals and locals['result'] > 100
    
    def bp_negative_input(locals, globals):
        return 'x' in locals and locals['x'] < 0
    
    # 添加断点
    debugger.add_breakpoint(bp_high_value, "结果值大于100")
    debugger.add_breakpoint(bp_negative_input, "输入值为负数")
    
    # 调试函数
    @debugger.debug_function
    def complex_calculation(x, y):
        result = x * y + (x + y) ** 2
        debugger.check_breakpoints(locals(), globals())
        return result
    
    # 测试调用
    test_cases = [(2, 3), (10, 5), (-1, 10), (8, 12)]
    
    for x, y in test_cases:
        print(f"\n计算: complex_calculation({x}, {y})")
        try:
            result = complex_calculation(x, y)
            print(f"结果: {result}")
        except Exception as e:
            print(f"错误: {e}")
    
    # 生成调试报告
    debugger.print_debug_report()

if __name__ == "__main__":
    demo_systematic_debugging()

9. 调试性能优化

9.1 生产环境调试策略

# production_debug.py
"""
生产环境调试策略
"""

import logging
import time
from functools import wraps

def production_debug(enable_tracing=False, slow_threshold=1.0):
    """生产环境调试装饰器"""
    def decorator(func):
        @wraps(func)
        def wrapper(*args, **kwargs):
            start_time = time.time()
            logger = logging.getLogger(func.__module__)
            
            # 记录函数开始
            if enable_tracing:
                logger.debug(f"函数开始: {func.__name__}")
            
            try:
                result = func(*args, **kwargs)
                execution_time = time.time() - start_time
                
                # 检查执行时间
                if execution_time > slow_threshold:
                    logger.warning(
                        f"函数执行缓慢: {func.__name__}, "
                        f"耗时: {execution_time:.2f}秒"
                    )
                
                if enable_tracing:
                    logger.debug(f"函数完成: {func.__name__}")
                
                return result
                
            except Exception as e:
                execution_time = time.time() - start_time
                logger.error(
                    f"函数执行错误: {func.__name__}, "
                    f"错误: {e}, 耗时: {execution_time:.2f}秒"
                )
                
                # 生产环境下的安全调试
                if os.getenv('ENABLE_PRODUCTION_DEBUG', 'false').lower() == 'true':
                    logger.info("进入生产环境调试模式")
                    import pdb
                    pdb.post_mortem()
                
                raise
        
        return wrapper
    return decorator

class PerformanceMonitor:
    """性能监控器"""
    
    def __init__(self):
        self.metrics = {}
        self.logger = logging.getLogger('performance')
    
    def track_performance(self, operation_name):
        """性能跟踪装饰器"""
        def decorator(func):
            @wraps(func)
            def wrapper(*args, **kwargs):
                start_time = time.time()
                start_memory = self._get_memory_usage()
                
                try:
                    result = func(*args, **kwargs)
                    return result
                finally:
                    end_time = time.time()
                    end_memory = self._get_memory_usage()
                    
                    execution_time = end_time - start_time
                    memory_used = end_memory - start_memory
                    
                    # 记录指标
                    self._record_metrics(
                        operation_name, execution_time, memory_used
                    )
                    
                    # 检查性能问题
                    self._check_performance_issues(
                        operation_name, execution_time, memory_used
                    )
            
            return wrapper
        return decorator
    
    def _get_memory_usage(self):
        """获取内存使用量"""
        import psutil
        process = psutil.Process()
        return process.memory_info().rss / 1024 / 1024  # MB
    
    def _record_metrics(self, operation, time_used, memory_used):
        """记录性能指标"""
        if operation not in self.metrics:
            self.metrics[operation] = {
                'count': 0,
                'total_time': 0,
                'max_time': 0,
                'total_memory': 0,
                'max_memory': 0
            }
        
        metrics = self.metrics[operation]
        metrics['count'] += 1
        metrics['total_time'] += time_used
        metrics['max_time'] = max(metrics['max_time'], time_used)
        metrics['total_memory'] += memory_used
        metrics['max_memory'] = max(metrics['max_memory'], memory_used)
    
    def _check_performance_issues(self, operation, time_used, memory_used):
        """检查性能问题"""
        # 时间阈值检查
        if time_used > 5.0:  # 5秒阈值
            self.logger.warning(
                f"操作 {operation} 执行时间过长: {time_used:.2f}秒"
            )
        
        # 内存阈值检查
        if memory_used > 100:  # 100MB阈值
            self.logger.warning(
                f"操作 {operation} 内存使用过多: {memory_used:.2f}MB"
            )
    
    def generate_report(self):
        """生成性能报告"""
        report = ["性能监控报告:", "="*50]
        
        for operation, metrics in self.metrics.items():
            avg_time = metrics['total_time'] / metrics['count']
            avg_memory = metrics['total_memory'] / metrics['count']
            
            report.extend([
                f"操作: {operation}",
                f"  调用次数: {metrics['count']}",
                f"  平均时间: {avg_time:.3f}秒",
                f"  最大时间: {metrics['max_time']:.3f}秒",
                f"  平均内存: {avg_memory:.2f}MB",
                f"  最大内存: {metrics['max_memory']:.2f}MB",
                ""
            ])
        
        return "\n".join(report)

# 使用示例
def demo_production_debugging():
    """演示生产环境调试"""
    monitor = PerformanceMonitor()
    
    @monitor.track_performance("数据计算")
    @production_debug(enable_tracing=True, slow_threshold=0.5)
    def heavy_calculation(n):
        """耗时的计算函数"""
        result = 0
        for i in range(n):
            result += i ** 2
            time.sleep(0.01)  # 模拟耗时操作
        return result
    
    # 测试调用
    for i in [100, 200, 300]:
        print(f"计算 n={i}")
        result = heavy_calculation(i)
        print(f"结果: {result}")
    
    # 生成报告
    print(monitor.generate_report())

if __name__ == "__main__":
    demo_production_debugging()

10. 总结

通过本文的全面介绍,我们深入探讨了Python PDB调试器的强大功能和使用技巧。从基础的断点设置到高级的远程调试,从简单的脚本调试到复杂的生产环境调试,PDB为Python开发者提供了全面的调试