调试与分析
大家好!这个章节我们要讨论的是调试和分析程序中的错误。写代码时,错误是不可避免的,但能否快速定位并修复错误,往往是一个程序员的核心技能之一。通过报错信息和调试技巧,我们可以大大提高解决问题的效率。接下来,我会带你们了解如何从错误信息中找到问题,并用一些实际的技巧帮助你们进行调试。
简介
在编写程序过程中,出现错误是再所难免的,出现错误后,如何能通过报错信息,快速找出并修复错误,是代码开发过程中非常重要的技能。
编程过程中,错误是常见的,尤其在复杂的代码中。错误信息的分析和快速定位问题是非常重要的技能。面对错误时,许多开发者可能会感到困惑,但如果能够熟练使用报错信息和调试工具,就能很快找出问题并解决。
错误分析
程序出现错误并中断结束后,出现报错信息的错误都是不可怕的,大多都是一些语法性的错误,通过错误提示信息,就可以快速定位和解决错误。

错误信息其实并不可怕,很多时候它给出了足够的提示,帮助我们快速定位错误。
错误分析:
- 错误所在的文件
- 错误所在的行
- 错误出现的代码
- 错误类型
- 错误原因描述
错误信息通常包括几个关键部分:错误所在的文件、行号、代码段和错误类型。了解这些信息,我们就能明确问题所在。比如你看到错误信息后,可以从中提取出:错误所在的文件名、错误发生的行号、错误涉及的代码、错误的类型、错误的详细描述。这些信息是我们分析和解决问题的基础。
有时候通过报错信息,并不能直接定位出错误,要通过报错信息,及程序的上下文逻辑来分析真正的报错原因。

有时错误信息并不能直接告诉我们问题的根源,这时就需要我们结合程序的上下文和逻辑来分析。错误提示可能指出了一些代码行,但问题的实际根源可能出现在代码的其他地方。
在上面的错误中,共提示了两处报错位置,分别是 12 行和 7 行,这是代码追踪提示。
但真正的错误并不在这里,通过错误原因描述发现,是在执行 range() 函数时,并不能将字符串类型的参数解释成一个数字。
从代码实现逻辑上看,output 函数并没有任何问题,结合上下文的代码逻辑发现,问题出在 getInputData 函数中的数据获取,从键盘输入的所有内容都是以字符串形式保存到程序变量中,程序要求获得一个数字,那么在键盘输入后,应该使用强制类型转换,将输入数据转换成数字。
n = input("请输入一个数字:") 修改为 n = int(input("请输入一个数字:"))
例如,在错误提示中,程序可能会报错在第 12 行和 7 行,但实际上问题是出现在变量类型上。比如在下面的错误信息中,程序报错是因为 range() 函数接收到了一个字符串类型的参数,而不是数字。通过错误信息,我们可以了解到问题的关键:输入值是字符串类型,而 range() 需要的是整数。因此,我们需要将输入值转换为整数。修改代码:n = int(input("请输入一个数字:"))
print 信息调试
很多人由于英文不太好,在查看报错信息时很吃力,也可以通过 print() 函数,自行输出信息来定位错误位置,虽然这种方式可以解决问题,但还是要慢慢学习,掌握如何查看报错提示。
如果你对错误信息不太熟悉,或者它不够清晰,可以通过 print() 函数来调试代码。通过输出中间变量的值和状态,我们能更容易地理解程序的执行过程。虽然 print() 调试方式很直接有效,但它不如使用专业的调试工具那么高效。因此,掌握如何查看和理解错误信息依然是非常重要的技能。
示例代码:
def getInputData():
print("input run")
n = input("请输入一个数字:")
msg = input("请输入一个数据:")
return n,msg
def outputData(n,msg):
print("output run")
for i in range(n):
print("output forin run")
print(msg)
if __name__ == '__main__':
n,msg = getInputData()
outputData(n, msg)
在下面的示例代码中,我们用 print() 输出了执行到哪些地方,从而帮助我们了解程序的执行流程。
运行结果:
input run
请输入一个数字:1
请输入一个数据:1
output run
Traceback (most recent call last):
File "/Users/liusuhui/Desktop/RecordCode/main.py", line 15, in <module>
outputData(n, msg)
File "/Users/liusuhui/Desktop/RecordCode/main.py", line 9, in outputData
for i in range(n):
TypeError: 'str' object cannot be interpreted as an integer
Process finished with exit code 1
运行结果中,input run 和 output run 都正常输出,而 output forin run 没有输出。这就说明程序在执行到循环之前就出错了。
在示例代码中,加入了三条 print() 语句,用来输出一些信息,通过运行结果可以看出,input run 和 output run 都被正常输出,而 output forin run 没有输出,说明程序在输出该语句之前出现错误,此时就可以通过检查语法信息,上下文逻辑等来判断具体错误原因。
print() 语句在调试代码时,两条语句之间包含多少代码,视具体情况而定。不是必须在每条语句前后都加 print() 输出,在错误调试完成后,需要把输出注释或删除掉。
这个时候,借助报错信息,我们能看到 range() 函数无法处理字符串类型的数据。解决方法就是强制将输入值转换为整数。
debug 调试
除了前面两种方式外,还可以通过 PyCharm 的 debug 功能来调试程序,通过 debug功能,还可以监控程序的执行过程。
在使用 debug 功能时,需要配合程序断点来进行调试。

除了使用 print() 外,PyCharm 提供的 debug 功能也是非常强大的调试工具。通过 debug,你可以监控程序的执行过程,逐行查看代码的执行结果,从而精确地定位错误。你只需要在代码中设置断点,程序执行时会在断点处暂停,这样你就可以查看程序在那一时刻的状态。
程序断点
使用 PyCharm 编写代码时,可以在行号后通过点击添加删除断点。
断点的作用是在 debug 调试程序时,遇到断点程序就会暂停执行,通过点击控制按钮,控制程序向下执行。

在 PyCharm 中,可以通过点击行号旁边的空白区域来设置断点。断点会让程序在执行到该行时暂停,等待你的操作。这时你可以查看当前的变量值、调用栈等信息,从而帮助你分析问题。
调试控制
程序打好断点后,点击 debug 即可进入 debug 模式,程序遇到断点就会暂停执行,此时就需要通过控制按钮来控制程序的执行

在调试模式下,PyCharm 提供了一些控制按钮,帮助你管理调试过程。
横向按钮
Step Over: 跳过按钮,将函数做为一条语句执行,不进入函数内部执行。Step Into: 单步执行,会进入到函数内部逐条执行代码。Step Into My Code: 单步执行,只进入自定义函数内部,不会进入系统函数内部。Step Out: 步出按钮,跳出当前函数体,返回到此函数调用位置Run to Cursor: 运行到光标处,当调试程序时,如果某一行没有打断点,又想暂停,可以将光标移动到目标行,点击该按钮Evaluate Expression: 评估表达式,高级用法,可以在调试过程中查看程序的中间过程,比如查看参数 n 的类型。
Step Over 是跳过按钮,将函数做为一条语句执行,不进入函数内部执行。Step Into 是进入当前行中调用的函数,逐行查看代码。Step Into My Code 表示只进入自定义函数,而不会进入第三方库的函数。Step Out 表示跳出当前函数,返回到函数调用的位置。Run to Cursor 表示运行到光标所在行,适用于没有设置断点的情况下。Evaluate Expression 可以查看变量值、类型等信息,非常适合调试复杂的表达式。这些调试控制按钮让你在调试时更加灵活,能够精准地控制程序的执行。
竖向按钮
Rerun main: 重新运行 debug 功能Modify Run Configuration: 修改运行配置Resume Program: 继续执行,运行到下一断点处,如果没有,程序运行结束Stop main: 停止 DebugView Breakpoints: 显示程序中所有的断点。Mute Breakpoints: 让所有断点失效,使用后所有断点为灰色,debug 时,代码不会在断点处暂停。Pin Tab: 钉住当前调试窗口标签,防止关闭。
除了横向按钮,PyCharm 还提供了一些竖向按钮来控制调试。Rerun main 表示重新运行调试。Modify Run Configuration 表示修改运行配置。Resume Program 表示继续执行程序,直到下一个断点。Stop main 表示停止调试。View Breakpoints 表示查看当前所有的断点。Mute Breakpoints 表示暂时禁用所有断点。
总结
- 错误分析
- print 信息调试
- debug 调试
今天我们学习了如何进行错误分析、使用 print() 语句调试和如何通过 debug 工具调试代码。错误分析是找出问题的第一步,print() 语句则是我们调试的常用工具,PyCharm 的 debug 功能则为我们提供了更精细的调试体验。掌握这些技巧,你就能快速定位问题,提升编程效率。