字符界面调试python程序的方法

在生产环境,我们一般会把项目布置在服务器上,和我们的本地调试环境不同,服务器一般都是无GUI界面的,一旦在生产环境出了问题,只能在字符界面下调试.于是乎,我们pycharm的断点大法彻底歇菜.那么,在字符界面,一般都用什么调试方式呢? 在这里,我推荐给大家的是jupyter+pdb/ipdb的组合来在字符界面进行调试.

首先说编辑器.很多人在windows环境下习惯了图形界面的人,可能不太适应vi之流的的字符界面的编辑器,觉得需要记忆的快捷键太多.而且python语法特有的缩进问题,很容易导致编辑后的py文件无法运行.那么,有什么好的替代方案吗? 有!,就是jupyter,也就是以前我们说的IPython notebook.以下逐步举例说明,注意,我用的是python3,对应的pip命令是pip3,如果你是python2,请自行改为pip命令.

先安装jupyter

pip3 install jupyter

然后切换到你的站点/项目目录,比如的项目目录在 /home/web/下面.我就:

cd /home/web/

运行jupyter

在项目根目录下面运行

jupyter notebook --ip=0.0.0.0 --port 8998 --allow-root

说明一下:
--ip 是你绑定的ip地址.
--port 是你绑定的端口.
--allow-root 如果你不是使用root账户的话,可以不加这一参数.
程序运行起来后,会有一行这样的提示:

Copy/paste this URL into your browser when you connect for the first time,
    to login with a token:
        http://0.0.0.0:8998/?token=8e70bede7af9ad0a9dd9120cb5eb1cfa8db32995021e18fd
字符界面调试python程序的方法_第1张图片
2018-04-11 15-53-42屏幕截图.png

意思让你用"http://0.0.0.0:8998/?token=8e70bede7af9ad0a9dd9120cb5eb1cfa8db32995021e18fd"这个地址登录,实际上,你要把0.0.0.0替换成真实的ip地址.比如"http://192.168.0.49:8998/?token=8e70bede7af9ad0a9dd9120cb5eb1cfa8db32995021e18fd"
然后就看见了项目目录:

字符界面调试python程序的方法_第2张图片
2018-04-11 15-55-42屏幕截图.png

这个时候,你就可以随意编辑服务器上的项目文件了.
字符界面调试python程序的方法_第3张图片
2018-04-11 15-56-53屏幕截图.png

安装 ipdb

其实这一步不是必须的,python 自带的pdb就足够了,但ipdb是个人偏好,我喜欢彩色的字.哈哈

pip3 install ipdb

软断点和硬断点

我们知道,一般我们使用ipdb调试的时候,使用的是软断点模式.

python3 -m ipdb your.py

-m参数是以脚本的形式运行python3下安装的库. 这个参数经常使用.

这样我们就可以以交互的方式使用 break line_number的方式打一个软断点,然后按c继续运行.我下面先举个例子.
我的代码是这样的. extends_func.py

# -*-coding:utf-8-*-
from uuid import uuid4


def add_uuid(part_str: str) -> str:
    """
    把一段字符串后面加上一段uuid,这么无聊的程序当然是用来演示啦.
    :param part_str: 字符串
    :return:part_str + uuid
    """
    if part_str is None:
        ms = "part_str参数不能为空"
        raise TypeError(ms)
    else:
        if not isinstance(part_str, str):
            part_str = str(part_str)
        else:
            pass
        return part_str + uuid4().hex


if __name__ == "__main__":
    add_uuid("a")
    pass

然后我们使用ipdb运行这个脚本

python3 -m ipdb extends_func.py

ipdb启动后,会停在脚本的开头,等待你输入命令.
这时候你可以使用break line_number打一个软断点,这个命令有个快捷方式,就是b.比如
b 11 就是在当前脚本的第11行打一个断点.b后面也可以跟一个函数名,这样断点就打在函数的入口处.当然断点你也可以打在其他脚本上,前提是你不要输错路径.
这里我们把断点打在当前脚本的第14行,在ipdb的提示符下输入 b 11 然后回车.

walle@walle-Vostro-3559:~/work/projects/flask_01$ python3 -m ipdb extends_func.py 
> /home/walle/work/projects/flask_01/extends_func.py(2)()
      1 # -*-coding:utf-8-*-
----> 2 from uuid import uuid4
      3 

ipdb> b 11
Breakpoint 1 at /home/walle/work/projects/flask_01/extends_func.py:11
ipdb> 

然后输入c回车,让程序继续运行.程序会在我们的断点位置停下,然后我们就可以做很多事情........

walle@walle-Vostro-3559:~/work/projects/flask_01$ python3 -m ipdb extends_func.py 
> /home/walle/work/projects/flask_01/extends_func.py(2)()
      1 # -*-coding:utf-8-*-
----> 2 from uuid import uuid4
      3 

ipdb> b 11
Breakpoint 1 at /home/walle/work/projects/flask_01/extends_func.py:11
ipdb> c
> /home/walle/work/projects/flask_01/extends_func.py(11)add_uuid()
     10     """
1--> 11     if part_str is None:
     12         ms = "part_str参数不能为空"

ipdb> 

这在一般的脚本调试中是很好用的,而且不像硬断点,对原始代码没有污染.不过,我们有很多web项目(比如flask项目),服务器脚本都是处于阻塞状态的, 这种软断点无法生效.只能使用硬断点的方式了.

设置硬断点

直接上代码

# -*-coding:utf-8-*-
from flask import Flask
from flask import request
from extends_func import add_uuid
from pdb import set_trace   # 引入跟踪函数


port = 7777
app = Flask(__name__)


@app.route("/")
def hello():
    set_trace()  # 设置硬断点
    name = request.args.get("name")
    res = add_uuid(name)
    return res


if __name__ == "__main__":
    app.run(host='0.0.0.0', port=port, debug=True)

然后我们另开一个窗口,把站点项目跑起来.

root@ubuntu-server:/home/web/flask_01# python3 f_server.py 

然后我们访问站点的首页.程序会在硬断点的位置停下来.

^Croot@ubuntu-server:/home/web/flask_01# python3 f_server.py 
  * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 303-929-595
> /home/web/flask_01/f_server.py(15)hello()
     14     set_trace()  # 设置硬断点
---> 15     name = request.args.get("name")
     16     res = add_uuid(name)

ipdb> 

然后你可以idb后面输入命令,进行调试了.常用的几个命令如下:

命令                                                          说明
n                                                               单步,不会进子程序
s                                                               单步,会进子程序
c                                                               跳到下个断点
p  arg_name                                             查看变量值,arg_name是变量名
l                                                                查看附近区域代码
b                                                               line_number  打软断点
condition break_number [expression]     条件断点,break_number断点编号,可以输入l查看,expression 是条件 比如 a is None
h                                                               帮助文件
var = value                                                赋值, 比如 name = 'jack'
cl [break_number]                                    清除断点 ,没有break_number是清除全部断点.
a                                                               打印当前函数的参数
q                                                               退出     

你可能感兴趣的:(字符界面调试python程序的方法)