python debug

debug方法千千万,分析一下这些可以分成哪几类?

  1. 直接看报错结果:比较清晰看到出错位置
    • 鸵鸟算法。。。
    • 抛出异常
    • logging
  2. 中途print:要求知道出错地方大致在哪里
    • print
    • assert
  3. 控制

Outline

  • assert介绍
  • logging介绍
  • pdb介绍(ipdb为增强版pdb)

Assert

assert expression [, arguments]

assert condition "sentence"

判断条件是否成立,如果不成立,则打印后面的句子并且结束程序

等价于

if not expression:
    raise AssertionError

eg

import sys
assert ('linux' in sys.platform), "该代码只能在 Linux 下执行"

Logging

基础介绍

logging是系统内置库,可以看作print的plus版,对于大一些的项目logging比print更合适。

logging日志有级别,在开发时可以打印所有的信息,帮助我们进行debug等;在项目上线时可能只需要打印info以上的信息。这种分级的打印减少开发与部署之间代码的改动

import logging  # 引入logging模块
# 将信息打印到控制台上
logging.debug(u"aaa")
logging.info(u"bbb")
logging.warning(u"ccc")
logging.error(u"ddd")
logging.critical(u"fff")

默认只打印warning以及以上的内容,手动设置级别只需简单配置一下

logging.baseConfig(level=logging.DEBUG)

需要注意的是,logging打印出的日志信息与print打印的信息在控制台上的顺序和代码中的顺序不一定是一致的,因为logging要控制并发的日志做了并发的处理;但是logging自己的打印信息顺序是正常的

更多功能

  • 输出到指定文件中(但此时不会显示在控制台中)(默认下次运行会追加内容)

    logging.baseConfig(filename='debug.log', level=logging.DEBUG)
    # 参数介绍
    # filemode: 写入模式 w a
    # format = "%{asctime}s|%{levelname}s|%{filename}s:%{lineno}s|%{message}s"
    # datefmt = "%Y-%m-%d %H:%M:%S"
    
  • 当出现错误时用try except来接住错误,并使用logging记录下来(用这种方法相比于直接看结果的缺点是缺少回溯信息)

    try:
        xxx
    except Exception as e:
        print('Error:',e)
        print(e.args)
        print(e.with_traceback()) # Traceback
        logging.critical(e)
    

    若想打印回溯信息

    e.with_traceback()
    

pdb

pdb是一种替代IDE在控制台进行调试的方法

pdb 模块定义了一个交互式源代码调试器,用于 Python 程序。它支持在源码行间设置(有条件的)断点和单步执行,检视堆栈帧,列出源码列表,以及在任何堆栈帧的上下文中运行任意 Python 代码。它还支持事后调试,可以在程序控制下调用。调试器的提示符是 (Pdb)

有两种使用方法

  1. 侵入式:在python代码中加入pdb

    import pdb
    pdb.set_trace() # 基本类似于设断点
    
  2. 非侵入式:不用额外修改源代码,在命令行下直接运行就能调试

    python -m pdb xxx.py
    

进入pdb调试界面后使用命令进行设断点、单步调试、打印变量等进一步调试

命令 使用方法 作用
h h or h 【cmd】 查看帮助
b b 3 b filename:line_no b line_no (第三行)设置断点
b b function 在函数function的第一条可执行语句处添加断点
tbreak - 临时断点,在第一次命中时会自动删除。它的参数与 break 相同
l l 打印当前环境上下文代码
n n
c c 继续执行(当后面存在断点时会再次暂停)
cl - 清除断点
s s 执行下一条命令(step)
r r 继续运行,直到当前函数返回(return)
n n 执行下一条语句(next)
【cmd】 - 像ipython一样控制程序
a a (args)列出当前执行函数的参数,查看函数参数
p p (print)输出expression的值,打印变量值
q q 推出debug