跳到主要内容

调试

程序很少能一次写对,总会有 bug;有的看错误信息就够,有的需要知道出错时变量的值。常用手段:printassertloggingpdbIDE

1. 用 print() 查看变量

  • 在可能有问题的地方 print(变量),运行后看输出。
  • 缺点:上线前要删掉;到处是 print 会输出很多无关信息。

2. 断言(assert)

  • 凡是用 print 辅助查看的地方,可用 assert 替代:assert 表达式, '错误信息';表达式应为 True,否则抛出 AssertionError
def foo(s):
n = int(s)
assert n != 0, 'n is zero!'
return 10 / n
  • 缺点:到处是 assert 也不理想。
  • 关闭 assert:用 python -O 脚本.py 启动(-O 是英文大写字母 O,不是数字 0),所有 assert 相当于 pass,不再执行。

3. logging(推荐)

  • print 换成 logging:不抛错,可输出到文件,可按级别控制输出。
  • logging.info('...') 等可输出文本;默认可能不显示,需先配置级别:logging.basicConfig(level=logging.INFO)
  • 级别debuginfowarningerror 等;指定 level=INFOdebug 不输出;指定 level=WARNINGdebuginfo 不输出。可放心写不同级别,不用删,统一用 level 控制输出哪一级。
  • 另一好处:通过配置可同时输出到控制台和文件
import logging
logging.basicConfig(level=logging.INFO)

n = int(s)
logging.info('n = %d' % n)

4. pdb(单步调试)

  • pdb 是 Python 自带的调试器,可单步执行、随时查看变量。

  • 启动python -m pdb 脚本.py,会停在第一行待执行代码。

  • 常用命令

    • l:查看当前附近代码
    • n:单步执行下一行
    • p 变量名:查看变量值
    • c:继续运行到下一个断点或结束
    • q:退出调试
  • 缺点:命令行单步到很远的一行很麻烦。

5. pdb.set_trace()(断点)

  • 不需从头单步:在可能出错处 import pdb 并加 pdb.set_trace(),运行到该行会自动暂停进入 pdb;再用 p 查变量、c 继续运行。
  • 比直接 python -m pdb 单步效率高,但仍不如 IDE 方便。
import pdb
s = '0'
n = int(s)
pdb.set_trace() # 运行到这里自动暂停
print(10 / n)

6. IDE 调试

  • 设断点、单步、看变量更顺手,用支持调试的 IDE
    • VS Code:需安装 Python 插件
    • PyCharm
    • Eclipse + pydev

小结

方式优点缺点
print简单直接要删、输出杂
assert可替代 print,失败即报错多了也乱;-O 可关掉
logging按级别控制、可写文件、不用删需配置 level
pdb单步、查变量命令行用着累
pdb.set_trace()断点暂停,比单步省事仍不如 IDE
IDE断点、单步、变量视图方便依赖环境
  • 结论:IDE 调试方便,但长期看 logging 才是终极武器——可分级、可落文件、不污染代码。

记忆:临时看用 print/assert,长期用 logging;要单步用 pdb 或 IDE;-O 关 assert。