python IDLE 的调试器

“调试器”是 IDLE 的一项功能,让你每次执行一行程序。调试器将运行一行代码,然后等待你告诉它继续。像这样让程序运行“在调试器之下”,你可以随便花多少时间,检查程序运行时任意一个时刻的变量的值。对于追踪缺陷,这是一个很有价值的工具。要启用 IDLE 的调试器,就在交互式环境窗口中点击 DebugDebugger。这将打开调试控制(Debug Control)窗口,如图 10-1 所示。

当调试控制窗口出现后,勾选全部 4 个复选框:Stack、Locals、Source 和 Globals。这样窗口将显示全部的调试信息。调试控制窗口显示时,只要你从文件编辑器运行程序,调试器就会在第一条指令之前暂停执行,并显示下面的信息:
• 将要执行的代码行;
• 所有局部变量及其值的列表;
• 所有全局变量及其值的列表。
你会注意到,在全局变量列表中,有一些变量你没有定义,诸如__builtins__、__doc__、__file__,等等。它们是 Python 在运行程序时,自动设置的变量。这些变量的含义超出了本书的范围,你可以暂时忽略它们。程序将保持暂停,直到你按下调试控制窗口的 5 个按钮中的一个:Go、Step、Over、Out 或 Quit。

Go

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

Step

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

Over

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

Out

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

Quit

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

调试一个数字相加的程序

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

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 或选择 Run->Run Module(启用 Debug->Debugger,选中调试控制窗口的所有 4 个复选框),程序启动时将暂停在第 1 行。调试器总是会暂停在它将要执行的代码行上。调试控制窗口看起来如图 10-2 所示。

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

再次点击 Over 按钮,执行 input() 函数调用,当 IDLE 等待你在交互式环境窗口中为 input() 调用输入内容时,调试控制窗口中的按钮将被禁用。输入 5 并按回车。调试控制窗口按钮将重新启用。继续点击 Over 按钮,输入 3 和 42 作为接下来的两个数,直到调试器位于第 7 行,程序中最后的 print() 调用。调试控制窗口应该如图 10-4 所示。

可以看到,在全局变量的部分,第一个、第二个和第三个变量设置为字符串值,而不是整型值。当最后一行执行时,这些字符串连接起来,而不是加起来,导致了这个缺陷。用调试器单步执行程序很有用,但也可能很慢。你常常希望程序正常运行,直到它到达特定的代码行。你可以使用断点,让调试器做到这一点。

断点

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

import random
heads = 0
for i in range(1, 1001):
	if random.randint(0, 1) == 1:
		heads = heads + 1
	if i == 500:
		print('Halfway down!')
print('Head 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 所示。

你不会在 if 语句上设置断点,因为 if 语句会在循环的每次迭代中都执行。通过在 if 语句内的代码上设置断点,调试器就会只在执行进入 if 语句时才中断。带有断点的代码行会在文件编辑器中以黄色高亮显示。如果在调试器下运行该程序,开始它会暂停在第一行,像平时一样。但如果点击 Go,程序将全速运行,直到设置了断点的代码行。然后可以点击Go、Over、Step 或Out,正常继续。如果希望清除断点,在文件编辑器中该行代码上点击右键,并从菜单中选择Clear Breakpoint。黄色高亮消失,以后调试器将不会在该行代码上中断。

猜你喜欢

转载自blog.csdn.net/dongyu1703/article/details/81985043