如何在使用pdb调试Python时打印所有变量值,而不指定每个变量?

ren*_*tov 48 python debugging pdb

我正在使用pdb调试我的Python脚本,手册说我可以使用p变量命令在某个点打印指定变量的值.但是,如果我有很多变量,比如20个变量,我想追踪所有这些变量的价值呢?如何在不指定每个手动的情况下打印所有这些?以此脚本为例:

a = 1
b = 2
c = 3
Run Code Online (Sandbox Code Playgroud)

我可以使用pdb调试它并使用pa,b,c打印所有这些,如下所示:

$ python -m pdb test.py 
> /media/test.py(1)<module>()
-> a = 1
(Pdb) n
> /media/test.py(2)<module>()
-> b = 2
(Pdb) n
> /media/test.py(3)<module>()
(Pdb) n
--Return--
> /media/test.py(3)<module>()->None
-> c = 3
(Pdb) p a, b, c
(1, 2, 3)
(Pdb) 
Run Code Online (Sandbox Code Playgroud)

但我必须手动指定每个变量.有没有一种方法可以一次打印所有变量,而无需指定每一个变量?

mun*_*unk 68

pdb是一个功能齐全的python shell,因此您可以执行任意命令.

locals()并且globals()将显示范围内的所有变量与他们的价值观.

dir()如果您对值不感兴趣,可以使用.

当你在Python中声明一个变量时,它会根据需要放入本地变量或全局变量中,并且由于其他原因,无法区分您定义的变量和范围内的变量.

当您使用dir()时,您感兴趣的变量很可能位于该列表的开头或结尾.如果你想获得密钥,值对

过滤本地人()可能看起来像:

>>> x = 10
>>> y = 20
>>> {k: v for k,v in locals().iteritems() if '__' not in k and 'pdb' not in k}
{'y': 20, 'x': 10}
Run Code Online (Sandbox Code Playgroud)

如果你的当地人()是一个真正的混乱,你需要一些更重的东西.您可以将以下函数放在python路径上的模块中,并在调试会话期间将其导入.

def debug_nice(locals_dict, keys=[]):
    globals()['types'] = `__import__`('types')
    exclude_keys = ['copyright', 'credits', 'False', 
                    'True', 'None', 'Ellipsis', 'quit']
    exclude_valuetypes = [types.BuiltinFunctionType,
                          types.BuiltinMethodType,
                          types.ModuleType,
                          types.TypeType,
                          types.FunctionType]
    return {k: v for k,v in locals_dict.iteritems() if not
               (k in keys or
                k in exclude_keys or
                type(v) in exclude_valuetypes) and
               k[0] != '_'}
Run Code Online (Sandbox Code Playgroud)

我在pastebin上添加了一个示例会话

有几个案例错过了.您可能希望扩展它以允许您传入类型.但它应该让你过滤除了你定义的变量以外的大部分内容.

DIR()

如果你只想要最后20个值,那么你得到的输出就像>>> p var1 var2 ... varn给你的那样,那么你最好切掉像dir()[ - 20:]这样的dir(),但你不会轻易看到变量和价值观.例如:"我在酒吧之前或之后宣布了foo吗?"

如果你想看到这种关系,你可以尝试这样的事情,假设你的变量在dir()的末尾.如果它们在开头,您可以进行不同的切片.如果您的变量不连续,这将无法正常工作.

>>> zip(dir(), [eval(var) for var in dir()])[-4:]
[('a', 10), ('var', 'var'), ('x', 30), ('y', 50)]
Run Code Online (Sandbox Code Playgroud)

  • @renatov 使用 locals() 或 globals() “返回一大堆非人类可读信息”,然后将它们与 pp (漂亮打印)命令一起使用。pp locals() 或 pp globals() (4认同)

OJF*_*ord 5

如此列表中针对多种语言所给出的:

a = 1
b = 1
n = 'value'
#dir() == ['__builtins__', '__doc__', '__name__', '__package__', 'a', 'b', 'n']
for var in dir()[4:]:
    value_of_var = eval(var)
    print(value_of_var)
Run Code Online (Sandbox Code Playgroud)

输出:

1
1
'value'
Run Code Online (Sandbox Code Playgroud)

给每一个贴上标签就像打印一样简单var + " equals " + eval(var)

您声明您的“理想输出”正是键入的结果p a, b, ... , n, ...

vars = []
for var in dir()[4:-1]
    vars.append(var)
print(tuple(vars))
Run Code Online (Sandbox Code Playgroud)

输出看起来像:

(1, 1, 'value')
Run Code Online (Sandbox Code Playgroud)