返回介绍

10.5 IDLE的调试器

发布于 2024-01-22 21:44:06 字数 4332 浏览 0 评论 0 收藏 0

“调试器”是IDLE的一项功能,让你每次执行一行程序。调试器将运行一行代码,然后等待你告诉它继续。像这样让程序运行“在调试器之下”,你可以随便花多少时间,检查程序运行时任意一个时刻的变量的值。对于追踪缺陷,这是一个很有价值的工具。

要启用IDLE的调试器,就在交互式环境窗口中点击DebugDebugger。这将打开调试控制(Debug Control)窗口,如图10-1所示。

图10-1 调试控制窗口

当调试控制窗口出现后,勾选全部4个复选框:Stack、Locals、Source和Globals。这样窗口将显示全部的调试信息。调试控制窗口显示时,只要你从文件编辑器运行程序,调试器就会在第一条指令之前暂停执行,并显示下面的信息:

· 将要执行的代码行;

· 所有局部变量及其值的列表;

· 所有全局变量及其值的列表。

你会注意到,在全局变量列表中,有一些变量你没有定义,诸如 builtins 、 doc 、 file ,等等。它们是Python在运行程序时,自动设置的变量。这些变量的含义超出了本书的范围,你可以暂时忽略它们。

程序将保持暂停,直到你按下调试控制窗口的5个按钮中的一个:Go、Step、Over、Out或Quit。

10.5.1 Go

点击Go按钮将导致程序正常执行至终止,或到达一个“断点”(断点在本章稍后介绍)。如果你完成了调试,希望程序正常继续,就点击Go按钮。

10.5.2 Step

点击Step按钮将导致调试器执行下一行代码,然后再次暂停。如果变量的值发生了变化,调试控制窗口的全局变量和局部变量列表就会更新。如果下一行代码是一个函数调用,调试器就会“步入”那个函数,跳到该函数的第一行代码。

10.5.3 Over

点击Over按扭将执行下一行代码,与Step按钮类似。但是,如果下一行代码是函数调用,Over按钮将“跨过”该函数的代码。该函数的代码将以全速执行,调试器将在该函数返回后暂停。例如,如果下一行代码是print() 调用,你实际上不关心内建print() 函数中的代码,只希望传递给它的字符串打印在屏幕上。出于这个原因,使用Over按钮比使用Step按钮更常见。

10.5.4 Out

点击Out按钮将导致调试器全速执行代码行,直到它从当前函数返回。如果你用Step按钮进入了一个函数,现在只想继续执行指令,直到该函数返回,那就点击Out按钮,从当前的函数调用“走出来”。

10.5.5 Quit

如果你希望完全停止调试,不必继续执行剩下的程序,就点击Quit按钮。Quite按钮将马上终止该程序。如果你希望再次正常运行你的程序,就再次选择DebugDebugger,禁用调试器。

10.5.6 调试一个数字相加的程序

打开一个新的文件编辑器窗口,输入以下代码:

print('Enter the first number to add:')
first = input()
print('Enter the second number to add:')
second = input()
print('Enter the third number to add:')
third = input()
print('The sum is ' + first + second + third)

将它保存为buggyAddingProgram.py,不启用调试器,第一次运行它。程序的输出像这样:

Enter the first number to add:
5
Enter the second number to add:
3
Enter the third number to add:
42
The sum is 5342

这个程序没有崩溃,但求和显然是错的。让我们启用调试控制窗口,再次运行它,这次在调试器控制之下。

当你按下F5或选择RunRun Module(启用DebugDebugger,选中调试控制窗口的所有4个复选框),程序启动时将暂停在第1行。调试器总是会暂停在它将要执行的代码行上。调试控制窗口看起来如图10-2所示。

图10-2 程序第一次在调试器下运行时的调试控制窗口

点击一次Over按钮,执行第一个print() 调用。这里应该使用Over按钮,而不是Step,因为你不希望进入到print() 函数的代码中。调试控制窗口将更新到第2行,文件编辑器窗口的第2行将高亮显示,如图10-3所示。这告诉你程序当前执行到 哪里。

图10-3 点击Over按钮后的调试控制窗口

再次点击Over按钮,执行input() 函数调用,当IDLE等待你在交互式环境窗口中为input() 调用输入内容时,调试控制窗口中的按钮将被禁用。输入5并按回车。调试控制窗口按钮将重新启用。

继续点击Over按钮,输入3和42作为接下来的两个数,直到调试器位于第7行,程序中最后的print() 调用。调试控制窗口应该如图10-4所示。可以看到,在全局变量的部分,第一个、第二个和第三个变量设置为字符串值,而不是整型值。当最后一行执行时,这些字符串连接起来,而不是加起来,导致了这个缺陷。

用调试器单步执行程序很有用,但也可能很慢。你常常希望程序正常运行,直到它到达特定的代码行。你可以使用断点,让调试器做到这一点。

10.5.7 断点

“断点”可以设置在特定的代码行上,当程序执行到达该行时,它迫使调试器暂停。在一个新的文件编辑器窗口中,输入以下程序,它模拟投掷1000次硬币。将它保存为coinFlip.py。

图10-4 在最后一行的调试控制窗口。这些变量被设置为字符串,导致了这个缺陷

 import random
 heads = 0
 for i in range(1, 1001):
❶      if random.randint(0, 1) == 1:
           heads = heads + 1
      if i == 500:
❷           print('Halfway done!')
 print('Heads came up ' + str(heads) + ' times.')

在半数时间里,random.randint(0,1)调用❶将返回0,在另外半数时间将返回1。这可以用来模拟50/50的硬币投掷,其中1代表正面。当不用调试器运行该程序时,它很快输出下面的内容:

Halfway done!
Heads came up 490 times.

如果启用调试器运行这个程序,就必须点击几千次Over按钮,程序才能结束。如果你对程序执行到一半时heads的值感兴趣,等1000次硬币投掷完500次,可以在代码行print('Halfway done!')❷上设置断点。要设置断点,在文件编辑器中该行代码上点击右键,并选择Set Breakpoint,如图10-5所示。

图10-5 设置断点

你不会在if语句上设置断点,因为if语句会在循环的每次迭代中都执行。通过在if语句内的代码上设置断点,调试器就会只在执行进入if语句时才中断。

带有断点的代码行会在文件编辑器中以黄色高亮显示。如果在调试器下运行该程序,开始它会暂停在第一行,像平时一样。但如果点击Go,程序将全速运行,直到设置了断点的代码行。然后可以点击Go、Over、Step或Out,正常继续。

如果希望清除断点,在文件编辑器中该行代码上点击右键,并从菜单中选择Clear Breakpoint。黄色高亮消失,以后调试器将不会在该行代码上中断。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文