Python调试器– Python pdb

时间:2020-02-23 14:42:37  来源:igfitidea点击:

Python pdb模块为开发人员提供调试Python程序的交互式调试环境。
今天,我们将探索使用pdb模块的python调试器示例,并介绍各种调试python程序的方法。

Python调试器– Python PDB

Python中的pdb模块为我们提供了巨大的功能,可以有效地调试python代码。
这包括:

  • 暂停程序
  • 看一下变量的值
  • 查看每一行的程序执行

这些只是使pdb模块成为Python程序员的福音的几点。
让我们看看如何开始使用此模块。

启动Python调试器

好吧,这与程序无关。
我们可以使用任何程序启动pdb。
这是一个示例程序:

class User:

  def __init__(self, runner):
      self.counter = runner

  def showSomething(self):
      for i in range(self.counter):
          print(i)
      return

user = User(5)
user.showSomething()

让我们看一下该程序的输出:

<p>We can go to next line in pdb execution by pressing 'n' followed by Enter key.</p>

在程序中启动pdb

上面的示例从命令行启动了" pdb",因此,pdb跟踪从执行的第一行开始。
通常,我们只想调试程序的某个特定区域,该区域在程序启动后很久才出现。

为此,我们在程序本身中使用了pdb。
让我们看一下代码片段:

import pdb

class User:

  def __init__(self, runner):
      self.counter = runner

  def showSomething(self):
      for i in range(self.counter):
          pdb.set_trace()
          print(i)
      return

user = User(5)
user.showSomething()

让我们看一下该程序的输出:按n和Enter键转到下一行,观察执行情况。

事后调试

程序完成执行过程后,将其中的错误调试称为事后调试。
该模块还支持以下功能:

import pdb

class User:

  def __init__(self, runner):
      self.counter = runner

  def showSomething(self):
      for i in range(self.runner):
          pdb.set_trace()
          print(i)
      return

user = User(5)
user.showSomething()

其中我们提到了不存在的" self.runner"。
我们可以在Python解释器内部尝试以下功能:

检查堆栈上的变量

完全使用调试器的要点之一是,我们应该能够检查程序堆栈以及在程序执行期间在堆栈上存储了哪些变量。
我们也可以使用pdb做到这一点。
让我们看一下代码片段:

import pdb

def recursive_calls(i = 5, output = 'somethign here'):
  if i > 0:
      recursive_calls(i - 1)
  else:
      pdb.set_trace()
      print(output)
  return

if __name__ == '__main__':
  recursive_calls()

这是一个简单的递归示例。
让我们看一下该程序的输出:

注意,我们使用了where命令在堆栈上打印变量。
我们还可以将特定变量打印为:

对于可能包含较大值(例如文件数据等)的变量,我们也可以漂亮地打印这些值。
因此,如果变量是data,我们可以运行以下命令:

pp data

Python pdb断点

使用n转到下一行很有用,但是如果您实际上知道其中停下来怎么办?而且,当您知道要实际停止的位置时,调试整个程序并在每一行中移动都是很麻烦的!

使用pdb,我们还可以使用断点。
为此,我们需要通知pdb将断点设置到哪一行。
这是一个示例程序和演示:

import pdb

def recursive_calls(i = 5, output = 'somethign here'):
  if i > 0:
      recursive_calls(i - 1)
  else:
      print(output)
  return

if __name__ == '__main__':
  recursive_calls()

实际上,这里没有异常。
让我们看一下该程序的演示:我们将break关键字与要设置断点的行号一起使用。

管理断点

正如在上一个演示中看到的那样,当我们将断点应用于行时,该断点被分配了一个标识符为"断点1"。
数字部分可以用作ID,以交互方式启用和禁用这些断点。
禁用带有disable关键字的断点将通知调试器在到达该行时不停止执行。
断点仍被存储但被忽略。