1,IDE的断点调试
最常用的方法就是 使用IDE的调试功能, 在关键代码处 设置断点, 查看关键变量的值。
什么是设置断点?
设置断点就是 设置某些代码行位置,当 程序运行 到这些位置,就会暂停执行。
我们在程序运行过程中, 查看某个变量的值,必须要让运行的程序能停在相应的位置。
下面我们就以Pycharm 为例,看一下。
首先看决定程序运行结果的关键变量和关键代码有哪些
上面这个程序大体分为2 步
- 从服务器获取销量信息
- 分析信息,获得最热销手机型号
首先第一步必须正确,也就是获取回来的销量信息是否和需求说的一致
所以我们可以在如下代码处设置断点
Pycharm要设置断点非常简单,在要设置断点的代码左边边框上,也就是上图的箭头指向的地方,点击一下鼠标就可以了。
设置好了后,就会出现上图所示的一个红点。
接下来,代码编辑界面,右键点击鼠标,选择debug 调试运行程序,如下图所示
注意不要选Run, Run是直接运行,不会停留在断点处
过一会儿就会发现,程序已debug模式运行了,并且会停留在刚才设置的断点处 。 如下所示
注意,高亮的一行,表示程序执行 暂停在此处,而且此处高亮行 代码 尚未执行
这时,我们想查看变量content的值(因为里面是获取的具体手机销售信息)。 由于当前暂停的一行还没有执行,所以content变量没有得到值,需要我们执行一行代码,把当前行执行结束,content变量才会被赋值。
那么怎样去执行一行代码呢?
IDE 通常有2种方式。
- 一种是step over, 对应下方圈起来的按钮
点击该按钮,IDE就会让当前的程序执行完当前行的代码。 如果该代码里面有函数调用,执行 不会暂停在函数里面 ,而是直接运行完所有的函数里面的代码, 暂停在 下一行代码。
- 另一种是step into, 对应下方圈起来的按钮
点击该按钮,IDE就会让当前的程序执行一步当前行代码。 如果该代码里面有函数调用,执行 就会暂停在函数里面 。
这里我们可以点击Step Over 的按钮,全部执行完当前行,光标就会停在下一行,同时下方的Variables窗口里面会显示变量content的值,如图所示
由于这个字符串比较长,我们可以点击箭头处的view, 就会弹出下面的信息框,显示出完整的变量内容
可以看出读出的内容没有错。
那么下一个要检查的关键的变量 在后面,获取每款手机销量,并进行判断的代码中。
所以,可以设置新的断点,如下图所示
然后点击下图所示按钮,表示继续调试程序,程序运行就会停在下一个断点处
这时候,如果我们仔细观察,要比较的两个变量 mostsoldcount 和 soldcount
细心的读者,就会发现这个两个变量的类型都是字符串。
对字符串进行大小的比较 ?? !!!
这就是问题所在:我们忘了把字符串转为整数类型了,导致比较销量大小的时候出现了问题。
这时,就可以结束调试。修改代码,加上转化为整数的操作,如下
soldcount = int(items[-2])
重新运行一下,发现结果如下
最热卖手机是 华为Mate10, 销量是 170
这下就正确了。
2,print出关键变量的值
如果我们运行程序的机器上没有安装IDE, 可以简单一些,直接用代码打印出关键变量的值。 检查是否符合我们的预期就可以了。
比如可以在上面的程序加上一些print语句
import requests
# 用requests获取销量信息
res = requests.get('https://cdn2.byhy.net/files/py/0016_price')
content = res.content.decode('utf8')
print(f'得到的字符串内容为:{content}')
# 下面两个变量记录当前找到的销量最多的手机和卖出数量
# 初识值都是None
mostsoldphone = None
mostsoldcount = None
for info in content.splitlines():
info = info.strip()
# 去掉空行
if not info:
continue
items = info.split(',')
# 销量在倒数第二列,获取销量信息
soldcount = items[-2]
# 型号在 第一列, 获取型号信息
phonetype = items[0]
# 如果前面已经有销量最多的手机记录,和当前这款手机销量比较
if mostsoldphone:
# 如果当前这款手机销量更高,把它置为最热卖手机
print(f'mostsoldcount为:{mostsoldcount}')
print(f'soldcount为:{soldcount}')
if mostsoldcount < soldcount:
print(f'程序判断 {mostsoldcount} < {soldcount}')
mostsoldcount = soldcount
mostsoldphone = phonetype
else:
print(f'程序判断 {mostsoldcount} > {soldcount}')
# 如果前面没有有销量最多的手机记录,说明这是第一条记录
# 暂时先把它置为最热卖手机
else:
mostsoldcount = soldcount
mostsoldphone = phonetype
print(f'最热卖手机是 {mostsoldphone}, 销量是 {mostsoldcount}')
运行结果如下
得到的字符串内容为:三星S8, 110,50,5200
三星Note8, 123,30,6800
华为Mate10, 170,170,4100
华为P10, 167,57,3300
小米 6, 133,81,2200
小米 mix, 173,61,3200
mostsoldcount为:50
soldcount为:30
程序判断 50 > 30
mostsoldcount为:50
soldcount为:170
程序判断 50 > 170
mostsoldcount为:50
soldcount为:57
程序判断 50 < 57
mostsoldcount为:57
soldcount为:81
程序判断 57 < 81
mostsoldcount为:81
soldcount为:61
程序判断 81 > 61
最热卖手机是 小米 6, 销量是 81
分析输出可以发现, 如下地方有明显异常
mostsoldcount为:50
soldcount为:170
程序判断 50 > 170
这时候可以,有些经验的程序员就会怀疑两个变量的类型是否是整数了,检查一下代码就可以发现原来是字符串,而不是整数。
3,使用哪种方法?
用 IDE 设置断点 和 添加打印语句 都可以调试程序。
那么我们该使用哪种方法呢?
通常在开发的时候,我们使用 IDE设置断点的方法, 因为毕竟比 添加打印语句 方便, 可以方便的查看任意变量 的值, 可以随意添加 断点。
但是有的时候,程序运行的环境没有 IDE, 比如 给用户使用了, 这时,出现问题,可以使用添加print 语句查看关键变量的方法进行调试。
有些软件程序,我们在开发的时候,就应该写代码 把一些关键信息 保存下来, 当然不是打印到屏幕,而是 写入日志文件中。 这样有些问题,有时候我们不需要修改代码,添加调试打印语句,直接看日志文件就能发现问题所在