首页 / Python3 入门教程 / 调试技巧

Python3 入门教程

调试技巧

本教程共 70 篇 · 第 40 篇 · 更新于 2026-07-22 · 约 6 分钟阅读

PythonPython3 入门教程调试loggingpdbtraceback

40. 调试技巧

本节目标:掌握从简单到复杂的四种调试手段,能根据场景选择 print、assert、logging 或 pdb。

代码写了难免出 bug。发现问题后,定位根因的速度决定了你的效率。这一章介绍 Python 里常用的调试工具,从「土办法」到「专业工具」都有。

第一招:print 调试法

别笑,print() 是最快、最直接的调试方式。变量值不对?打印出来看看。

def calculate_discount(price, level):
    print(f"[DEBUG] price={price}, level={level}")
    if level == 'vip':
        return price * 0.8
    return price

result = calculate_discount(100, 'vip')
print(f"[DEBUG] result={result}")

进阶一点,用 f-string= 语法(Python 3.8+):

x = 10
print(f"{x=}")      # x=10
print(f"{x * 2=}")  # x * 2=20
Tip

print 适合临时排查、逻辑简单的问题。改完记得删掉或注释掉,别留在生产代码里污染环境。

第二招:assert 断言

assert 后面跟一个条件,条件为假时抛 AssertionError

def divide(a, b):
    assert b != 0, "除数不能为零"
    return a / b

# divide(10, 0)  # AssertionError: 除数不能为零

断言用来检查「不应该发生」的情况。它是给开发者看的,不是给用户看的错误处理。

Warning

运行 Python 时加 -O 参数(优化模式),所有 assert 会被跳过。所以永远不要把关键的业务校验放在 assert 里。

python -O myscript.py

第三招:logging 日志

print 的输出混杂在程序正常输出里,很难区分。logging 模块提供了分级别的日志系统:

import logging

logging.basicConfig(
    level=logging.DEBUG,
    format='%(asctime)s - %(levelname)s - %(message)s'
)

logging.debug('这是调试信息')
logging.info('程序正常启动')
logging.warning('磁盘空间不足 10%')
logging.error('数据库连接失败')
logging.critical('系统崩溃,立即处理')

日志级别从低到高:DEBUG < INFO < WARNING < ERROR < CRITICAL。设置 level=logging.INFO 后,debug 级别的日志不会输出。

Note

生产环境不要把日志直接打屏幕,应该写到文件:filename='app.log'。还可以按大小或日期切割,避免单个文件过大。

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename='app.log',
    encoding='utf-8'
)

日志比 print 专业得多,但配置略复杂。项目里建议统一封装一个日志模块,各业务代码直接调用。

第四招:pdb 交互式调试

遇到复杂逻辑,print 要打很多行,还容易看错。pdb(Python Debugger)让你像操作 IDE 一样,在代码执行过程中暂停、查看、单步跟踪。

在代码里插入断点

import pdb

def complex_calculation(a, b, c):
    x = a + b
    pdb.set_trace()  # 执行到这里会暂停
    y = x * c
    return y

complex_calculation(1, 2, 3)

运行后,程序在 pdb.set_trace() 处暂停,进入交互式调试模式。常用命令:

命令简写作用
nextn执行下一行,不进入函数内部
steps执行下一行,进入函数内部
continuec继续执行,直到下一个断点
printp打印变量值,如 p x
listl显示当前代码上下文
quitq退出调试

Python 3.7+ 的断点函数

Python 3.7 引入了 breakpoint(),它是 pdb.set_trace() 的现代化替代品:

def complex_calculation(a, b, c):
    x = a + b
    breakpoint()  # 更简洁的断点
    y = x * c
    return y

功能完全一样,但写法更短,而且可以通过环境变量切换不同的调试后端。

Tip

如果你用 VSCode 或 PyCharm,直接在代码行号左边点一下就能设断点,体验比 pdb 好很多。但 pdb 不依赖任何 IDE,在服务器上调试时它是唯一选择。

第五招:traceback 分析

程序崩溃时,Python 会打印 traceback(回溯信息)。学会读懂它,能帮你快速定位问题。

def foo():
    bar()

def bar():
    1 / 0

foo()

报错输出:

Traceback (most recent call last):
  File "demo.py", line 9, in <module>
    foo()
  File "demo.py", line 2, in foo
    bar()
  File "demo.py", line 6, in bar
    1 / 0
ZeroDivisionError: division by zero

阅读顺序:从下往上。最下面一行是「根因」:ZeroDivisionError: division by zero。往上是调用链:bar()foo() 调用,foo() 在模块顶层被调用。

Note

如果报错信息里出现了你写的代码和第三方库的代码混在一起,重点看「文件路径属于你项目」的那些行。第三方库的 bug 比较少见,问题大概率出在你的调用方式上。

调试策略的选择

场景推荐工具
临时看一眼变量值print() / f-string
检查内部不变量(开发时)assert
线上环境记录运行状态logging
复杂逻辑逐步跟踪pdb / IDE 断点
分析崩溃原因阅读 traceback

没有最好的工具,只有最合适的工具。小脚本用 print 最快,线上服务必须用 logging,复杂算法用 pdb 最稳。

小结

  • print 最直接,用完记得清理。
  • assert 做内部检查,不要用于业务校验。
  • logging 是生产环境的标配,分级别、可持久化。
  • pdb / breakpoint() 让程序暂停,逐步排查。
  • 读懂 traceback 是基本功,从下往上读。

调试是编程的一部分,不是「代码写错了才需要」。老手和新手的区别,往往在于定位问题的速度。多练几种工具,遇到 bug 时才不会手忙脚乱。


来源:参考了 liaoxuefeng「调试」、runoob「Python3 错误和异常」等,改写后所得。