Python 调试技巧与方法整理

整理了一下 python 调试的一些库的使用.

  1. pdb 类调试
  2. 日志类

https://github.com/510908220/python-debugging-skills

相信大家一定会喜欢上这些库的,确实方便多了。


Python 调试技巧与方法整理
17 回复

不要给我说什么底层原理、框架内核!老夫调试只用 print


Python 调试技巧与方法整理

1. print() 调试法

最简单直接的方法,在关键位置打印变量值:

def calculate_total(price, quantity):
    print(f"[DEBUG] price={price}, quantity={quantity}")
    total = price * quantity
    print(f"[DEBUG] total={total}")
    return total

2. pdb 交互式调试器

Python 内置的调试工具,功能最全面:

import pdb

def buggy_function(x, y):
    result = 0
    pdb.set_trace()  # 在此处进入调试模式
    for i in range(x):
        result += y * i
    return result

# 常用命令:
# n(ext) - 执行下一行
# s(tep) - 进入函数内部
# c(ontinue) - 继续执行到下一个断点
# l(ist) - 查看当前代码
# p <变量名> - 打印变量值
# q(uit) - 退出调试

3. breakpoint() 函数(Python 3.7+)

更现代的断点设置方式:

def process_data(data_list):
    total = 0
    for item in data_list:
        breakpoint()  # 相当于 pdb.set_trace()
        total += int(item)
    return total

4. 日志调试

使用 logging 模块进行结构化调试:

import logging

logging.basicConfig(level=logging.DEBUG)
logger = logging.getLogger(__name__)

def complex_calculation(a, b):
    logger.debug(f"Starting calculation with a={a}, b={b}")
    try:
        result = a / b
        logger.debug(f"Calculation result: {result}")
        return result
    except ZeroDivisionError:
        logger.error("Division by zero attempted")
        return None

5. 断言调试

在代码中加入检查点:

def validate_user_input(username, age):
    assert isinstance(username, str), "Username must be string"
    assert age >= 0, "Age cannot be negative"
    assert len(username) > 0, "Username cannot be empty"
    # 正常处理逻辑...

6. IDE 调试器(以 VS Code 为例)

  1. 点击行号左侧设置断点(红点)
  2. F5 启动调试
  3. 使用调试工具栏:
    • 继续 (F5)
    • 单步跳过 (F10)
    • 单步进入 (F11)
    • 重启 (Ctrl+Shift+F5)
  4. 在调试控制台直接执行 Python 代码

7. 异常追踪

捕获异常并获取详细信息:

import traceback

def risky_operation():
    try:
        # 可能出错的代码
        result = 1 / 0
    except Exception as e:
        print(f"Error occurred: {e}")
        traceback.print_exc()  # 打印完整的调用栈

8. 条件断点

在循环或特定条件下触发断点:

def find_bug_in_loop(data):
    for i, value in enumerate(data):
        if value > 100:  # 条件断点
            breakpoint()  # 当值大于100时触发
        process(value)

9. 远程调试

调试远程服务器上的代码:

# 服务端代码
import pdb
pdb.set_trace()  # 或使用远程调试工具如 rpdb

# 客户端连接
# telnet localhost 4444

10. 调试装饰器

创建自定义调试工具:

def debug_decorator(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__} with args={args}, kwargs={kwargs}")
        result = func(*args, **kwargs)
        print(f"{func.__name__} returned {result}")
        return result
    return wrapper

@debug_decorator
def add_numbers(a, b):
    return a + b

实用技巧总结

  • 快速切换:开发时用 print,复杂问题用 pdb
  • 二分法定位:通过注释代码快速缩小问题范围
  • 最小复现:创建能重现问题的最小代码片段
  • 变量监控:使用调试器监控特定变量变化
  • 调用栈分析:异常时查看完整调用链

一句话建议:根据问题复杂度选择合适的调试工具,print 适合简单问题,pdb 处理复杂逻辑。

分布式调试除了看 log 别无他法了吧

本地调试我还是推荐 ipython embed

但是用像 better-exceptions 这样的库,日志信息更完善,也是很有帮助的

带上我

我了解一下,谢谢

本地 print,服务器上 log,三年了…

虽然感觉有很多调试库 但是还是 print 顺手啊…

直接 print 调试。。。

better-excepttion 和 tornado 在一起,有什么最佳实践吗

膜拜插件大佬

默默的从你的参考转到 python3.8 的新功能介绍。:=不是 go 的么。。

pdb 是什么?没听过。
老夫只会 pycharm 行号上点个红点

断点调试咯

回到顶部