第六章介绍到完美的程序是不存在的,程序存在缺陷是常态,那么我们如何预先将潜在的缺陷给揪出来fix掉呢? 我们先思考一下这个问题,为什么程序运行出现错误呢? 程序 = 算法
第六章介绍到完美的程序是不存在的,程序存在缺陷是常态,那么我们如何预先将潜在的缺陷给揪出来fix掉呢?
我们先思考一下这个问题,为什么程序运行出现错误呢?
程序 = 算法 + 数据衡量算法的质量,可以从时间复杂度、空间复杂度来考虑。时间复杂度即算法的运行效率,空间复杂度即算法运行过程占用的内存空间。
数据就不用说了,任何程序的执行都是对数据的处理,数据的类型、大小都会影响程序能否正常运行。
综上,程序运行错误原因来源可以归纳为程序运行占用内存过高(内存溢出)、数据有误。所以回答文初我们提出的问题,如何识别曲缺陷呢?答案就是调试程序。其实调试程序很大一部分工作就是确定程序运行过程中,“投喂”给函数的数据是否正确。
很幸运,Pycharm自身的Debug模式就很强大且高效,所以本章就介绍一下如何使用Pycharm调试我们的程序。
8.1 熟悉控制台
Part One: 调试按钮
Part Two: 断点
如果你并不完全清楚缺陷来自哪里,异常可能毁掉您的一天,所以我们可以尝试在可能出现错误的地方打断点观察程序运行此处时,此时的数据是否符合我们的预期。
Part Three:调试控制台
Pycharm官网给出的解释:
1. show execution point 显示当前所有断点2. step over(F8) 单步调试,跳过子函数。
若函数A内存在子函数a时,不会进入子函数a内执行单步调试,而是把子函数a当作一个整体,一步执行。
3. step into(F7) 单步执行,遇到子函数就进入并且继续单步执行;
若函数A内存在子函数a时,会进入子函数a内执行单步调试。
4. step into my code 执行下一行但忽略libraries(导入库的语句)
5. force step into 执行下一行忽略lib和构造对象等
6. step out 当目前执行在子函数a中时,选择该调试操作可以直接跳出子函数a,而不用继续执行子函数a中的剩余代码。并返回上一层函数。
7. run to cursor 直接跳到下一个断点
8. Rerun 重新调试
9. Resume Program,顺序跳到下一个断点
8.2 调试实践
下面就以一个程序演示一下调试过程
假如我们想开发一个对list进行求和的程序,小白的写法如下:
def sums(list):total = 0
for i in list:
total = + i
return total
def debug_func(list):
return sums(list)
if __name__ == '__main__':
nums = [1, 3, 4, 5, 7, 8]
print(debug_func(nums))
>> 8
运行结果为8,怎么和预期28不一致呢?
点击F8(Step Over),运行程序,查看每次循环过程total的值是多少。通过调试发现每次循环执行后,total的取值等于i值,即total没有进行相加。
????debug.webm
此处为语雀视频卡片,点击链接查看:debug.webm