Python 调试

摘要:
此时,我们需要一个远程调试工具。

【简介调试工具】

pdb
使用如下代码就相当于添加断点了:
import pdb    
pdb.set_trace()  #设置断点的地方,放置于程序中

ipdb
相对于python,我们更趋向于ipython,有漂亮的颜色,和<tab>补全提示,以及bash混用;

相对于python内置的pdb,ipdb的优势也正在于此,其实就是对ipython的调用:

import ipdb
ipdb.set_trace()

pudb
是全屏的基于控制台的可视化调试器,有点像c语言中的Turbo C样式

wKioL1hCYYHRI1AAAACFZHN1Rc0206.png

为了支持pudb,需要在代码中插入
from pudb import set_trace; set_trace()  or  import pudb

rpdb
上面的两种方案要求有终端输出的情况下可行,有时候我们需要以后台形式执行python,此时是没有输出交互的,比如django开发,程序由uwsgi管理执行,标准输出已重定向,通常只能通过日志输出信息。这个时候我们就需要一个远程调试工具。
rpdb会开启一个socket连接,用于远程调试,默认端口是4444:
import rpdb
rpdb.set_trace(port=12345)
这样当程序被hang住之后,会监听该端口,可远程连接进行调试:
nc 127.0.0.1 12345

ripdb
rpdb只是pdb的远程版本,而ripdb就是将rpdb和ipdb的功能进行了整合,既有远程调试功能,又有漂亮的代码颜色:
import ripdb
ripdb.set_trace(port=12345)
如果还需要<Tab>自动补全功能,还需要对终端进行一下设置:
SAVED_STTY=`stty -g`; stty -icanon -opost -echo -echoe -echok -echoctl -echoke; nc 127.0.0.1 12345; stty $SAVED_STTY

【详解pdb/ipdb】

试验程序:传两个参数,进行加法和减法

1
2
3
4
5
6
7
8
9
10
11
12
13
import sys
def add(num1=0, num2=0):
    return int(num1) + int(num2)
def sub(num1=0, num2=0):
    return int(num1) - int(num2)
def main():
    print sys.argv
    addition = add(sys.argv[1], sys.argv[2])
    print addition
    subtraction = sub(sys.argv[1], sys.argv[2])
    print subtraction
if __name__ == '__main__':
    main()

1、进入PDB调试,其实就是一个交互式源代码调试器;修改程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import pdb   # 添加模块
import sys
def add(num1=0, num2=0):
    return int(num1) + int(num2)
def sub(num1=0, num2=0):
    return int(num1) - int(num2)
def main():
    print sys.argv
    pdb.set_trace()  # <-- Break point added here,设置的断点
    addition = add(sys.argv[1], sys.argv[2])
    print addition
    subtraction = sub(sys.argv[1], sys.argv[2])
    print subtraction
if __name__ == '__main__':
    main()

2、程序执行触发调试器  
执行:python 3_pdb.py  1 3  //程序在第一个断点处停止,如下

wKioL1hCYsmQWwQkAAAUkoyAtno306.png

此时我们可以看到程序在print sys.argv 处出了一个断点

并显示下一步将要执行 addition = add(sys.argv[1], sys.argv[2])

3、下一行  -> n  
输入“n”回车,将会执行addition = add(sys.argv[1], sys.argv[2]),然后打印出下一步操作;
但是会有一个问题,pdb没有进入到add函数中,下面的s选项可以解决此问题

wKiom1hCYzXSfvTeAAAhQqpbBnA422.png

4、打印 -> p  
在执行过程中我们想看,某个变量的打印值,除了c可以直接跳到下一个断点,打印期间所有值
“p”可以打印出某个变量的值,但前提是已经执行过这个变量。如下:

wKiom1hCY2WCTYo_AAAm3dLANS0678.png

5、单步 -> s  
“s”可以进入某个函数内部,然后再函数内使用n/p/b/c等
“r”将返回前面进入函数的返回语句

wKioL1hCY4_R6jV6AAA6AukGwK0704.png

6、添加动态断点 -> b  
在程序里,我们设置了一个断点,但当我们执行很长的代码时,忘了在脚本中设置断点

我们就可以直接用“b”在此环境下设置下一个断点位置
格式:b  行数
7、列表 -> l  
有时再调试时,不知道自己运行到哪,也不知道下面代码是什么了,为了不退出去去记某一行是什么,便可以执行小写“L”查看后面程序

wKiom1hCY-Din4hJAABvn5xA7H8570.png

8、动态分配变量  
在调试期间,可以分配变量帮助进行调试,
(Pdb) !n=5
(Pdb) p n
5

9、结束 -> q/exit  
在调试过程,想退出结束调试,可直接运行“q”或“exit”回车即可
--------------------------------------------------------------------------------------------------
PDB文档:https://docs.python.org/2/library/pdb.html  
而ipdb用法和pdb类似,只是更友好,更直观,如下:  

转载:http://tengxiansheng.blog.51cto.com/10693373/1879356

wKiom1hCZDGzIyVIAABRuVQqSMo534.png

免责声明:文章转载自《Python 调试》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇【SEED Labs】DNS Rebinding Attack LabSpring Boot版本号说明下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python 在不同层级目录import 模块的方法

有一个文件夹/home/a,  里面有个模块叫b.py,  我怎么把他import到程序里? 1). import sys; sys.path.append("/home/a/") import b 2). 在目录里面增加__init__.py文件,里面可以写import时执行的代码,当然也可以留空就可以. import home.a.b 3)....

python websocket Django 实时消息推送

概述: WebSocket 是什么? WebSocket 是 HTML5 提供的一种浏览器与服务器间进行全双工通讯的协议。依靠这种协议可以实现客户端和服务器端 ,一次握手,双向实时通信。 WebSocket 服务端: 用的是 dwebsocket,安装命令pip installdwebsocket. WebSocket 基本方法: 1.request.i...

python数据挖掘介绍

目录 一:什么是数据挖掘 二:数据挖掘的基本任务 三:数据挖掘流程 四:数据挖掘建模工具   在python对数据的处理方式中,数据挖掘和数据分析是两个重要的方式,目的是为了从数据中获取具有科研或者商业价值的信息。而数据挖则掘是从大量的数据中通过算法搜索隐藏在数据中隐含的、先前未知的并有潜在使用价值的信息的过程。本篇将讨论数据挖掘的一些入门知识。...

python逆向工程:通过代码生成类图

python逆向工程:通过代码生成类图 大致过程 现在有一个core包,里面有python的代码。 通过core包,生成python的类图,如下: 实施步骤: 1、首先安装graphviz,一个画图工具,地址为:http://www.graphviz.org/pub/graphviz/stable/windows/graphviz-2.28.0.msi...

linux环境安装opencv导入依赖报错问题

linux环境通过pip安装opencv后,导入cv2时报错: 在centos和ubuntu环境下都遇到相同的问题。报错原因: 缺少共享库有两种解决办法:一.使用如下命令查看缺少得共享库yum whatprovides libSM.so.6使用以下命令解决:yum install libSM-1.2.2-2.el7.x86_64 --setopt=prot...

python网编_进程之开启一个进程

直接上代码: importtime,os from multiprocessing importProcess # 导入模块 deffunc(): time.sleep(1) print('hello',os.getpid()) #os.getpid()的作用是打印进程id if __name__ == '__main__':...