如何在pdb中调试手动输入的表达式和语句?

Lea*_*rtS 6 python debugging expression pdb

在pdb(或ipdb)中,我们可以使用!p命令执行语句和计算表达式:

p expression
     在当前上下文中计算表达式并打印其值.

[!]声明

     在当前堆栈帧的上下文中执行(一行)语句.除非语句的第一个单词类似于调试器命令,否则可以省略感叹号.要设置全局变量,可以在赋值命令的前缀为同一行的全局命令

因此,例如,我可以p reddit.get_subreddits()在ipdb中调试时键入,代码将在当前上下文中执行,我将看到返回值.

有没有办法可以调试这种"手动输入"表达式的执行?

基本上我想做的是s reddit.get_subreddits(),但只是执行step命令并忽略表达式.

编辑:一个简单的例子

采取这个简单的功能:

import random

def get_value_for_weekday(weekday_index=None):
    values = [10, 20, 20, 10, 30, 30, 30]
    if not weekday_index:
        # If no weekday provided, return the average of all weekdays
        return sum(values) / 7
    return averages[weekday_index]

if __name__ == '__main__':
    while True:
        import ipdb; ipdb.set_trace()  # enter ipbd for debug
        get_value_for_weekday(random.randint(0, 7))
Run Code Online (Sandbox Code Playgroud)

由于if not weekday_index(它应该检查weekday_index is not None)而被窃听.

我们假设我注意到我的10预期次数减少了一半.所以我import ipdb; ipdb.set_trace()在调用函数之前添加了一个尝试调试代码的函数.

所以我在ipdb控制台,我突然想到可能问题是当我作为weekday_index传递0时.我可以直接在ipdb中测试我的假设:

ipdb> p get_value_for_weekday(0)
22
Run Code Online (Sandbox Code Playgroud)

好的,所以我意识到什么时候出错了weekday_index=0.
我现在要做的是逐步调试调用get_value_for_weekday(0),以便我可以看到我错误地输入if块.

显然我可以退出ipdb,停止脚本,将代码更改为始终传递0,重新启动脚本,当我输入ipdb时,使用ipdb step(s)命令调试调用.
但是,如果我能s get_value_for_weekday(0)以同样的方式做很多事情,那会不会更容易p get_value_for_weekday(0)

有没有办法做这样的事情?

Jim*_*ard 5

我认为您正在寻找由于(d)ebug某种原因未在调试器命令中指定的命令.仅供将来参考,pdb指定一组很好的命令(您可以通过help在交互式提示中键入来查看).在debug命令上:

(Pdb) help debug
debug code
        Enter a recursive debugger that steps through the code
        argument (which is an arbitrary expression or statement to be
        executed in the current environment).
Run Code Online (Sandbox Code Playgroud)

这似乎是你所追求的.使用终端中的示例脚本:

python -m pdb pdbscript.py
Run Code Online (Sandbox Code Playgroud)

发出两个n命令后,为了解析函数(我相信这是pdb有效的).您可以发出debug get_value_for_weekday(0)命令以递归方式进入函数:

(Pdb) debug get_value_for_weekday(0)
ENTERING RECURSIVE DEBUGGER
> <string>(1)<module>()
((Pdb)) s
--Call--
> /home/jim/Desktop/pdbscript.py(3)get_value_for_weekday()
-> def get_value_for_weekday(weekday_index=None):
((Pdb)) n
> /home/jim/Desktop/pdbscript.py(4)get_value_for_weekday()
-> values = [10, 20, 20, 10, 30, 30, 30]
((Pdb)) n 
> /home/jim/Desktop/pdbscript.py(5)get_value_for_weekday()
-> if not weekday_index:
((Pdb)) p weekday_index
0
((Pdb)) n
> /home/jim/Desktop/pdbscript.py(7)get_value_for_weekday()
-> return sum(values) / 7
Run Code Online (Sandbox Code Playgroud)

请注意,我觉得这种形式的元调试非常粗略,但它似乎是你所追求的.


Tom*_*oim 1

对于您的示例,您不需要退出 pdb 并更改代码。您可以单步进入该函数(使用“s”)并在内部设置 weekday_index=0 。

解决原始问题的一种方法是使用调试器的跳转命令,如下所示:

  1. 使用 'j #line-number' 在函数调用之前跳转
  2. 用 's' 进入函数
  3. 设置输入参数,然后继续调试。

当我尝试它时,这是有效的,但是当我出于某种原因尝试在步骤 2 之前执行步骤 3 时,调试器会抱怨。