在使用pdb调试Python时,如何打印所有变量值,而不指定每个变量? [英] How to print all variables values when debugging Python with pdb, without specifying each variable?

查看:1251
本文介绍了在使用pdb调试Python时,如何打印所有变量值,而不指定每个变量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 pdb 调试我的Python脚本,并且手册说我可以使用 p变量命令来打印特定变量的值。但是如果我有很多变量,如20个变量,我想跟踪所有这些变量的值呢?如何手动打印所有这些?以此脚本为例:

  a = 1 
b = 2
c = 3

我可以使用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
- 返回 -
> /media/test.py(3)<module>()->None
- > c = 3
(Pdb)pa,b,c
(1,2,3)
(Pdb)

但是我必须手动指定每个变量。有没有一种打印所有变量的方式,没有指定每个变量?

解决方案

pdb是一个功能齐全的python shell ,所以你可以执行任意命令。



localals() globals() / code>将显示范围中的所有变量及其值。



您可以使用 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}

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

  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 key or
k in exclude_keys or
type (v)in exclude_valuetypes)和
k [0]!='_'}

pastebin 上添加了一个示例会话



有几种情况,这个错过。而且你可能希望扩展它以允许您传递类型。但是,它应该让你过滤掉除了您定义的变量之外的所有东西。



dir()



如果你只想要最后20个值,所以你得到的输出像>>> p var1 var2 ... varn 会给你,那么你最好切割dir()像dir()[ - 20:],但是你不会轻易看到关系在变量和值之间。例如:我在酒吧之前还是之后声明foo?



如果你想看到这种关系,你可以尝试这样的东西,它假设你的变量在dir()的结尾。如果开始时你可以不同地切片。如果您的变量不连续,这将无法正常工作。

 >>> zip(dir(),[dir()中的var的eval(var)])[ -  4:] 
[('a',10),('var','var'),('x ',30),('y',50)]


I'm debugging my Python scripts using pdb and the manual says I can use p variables command to print the values of the specified variables at a certain point. But what if I had lots of variables, like 20 variables, and I would like to track the value of all of them? How do I print all of them without specifying each one manually? Take for example this script:

a = 1
b = 2
c = 3

I can debug it with pdb and print all of them using p a, b, c like this:

$ 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) 

But I have to manually specify each variable. Is there a way of print all variables at once, without specifying each one of them?

解决方案

pdb is a fully featured python shell, so you can execute arbitrary commands.

locals() and globals() will display all the variables in scope with their values.

You can use dir() if you're not interested in the values.

When you declare a variable in Python, it's put into locals or globals as appropriate, and there's no way to distinguish a variable you defined and something that's in your scope for another reason.

When you use dir(), it's likely that the variables you're interested in are at the beginning or end of that list. If you want to get the key, value pairs

Filtering locals() might look something like:

>>> 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}

If your locals() is a real mess, you'll need something a little more heavy handed. You can put the following function in a module on your pythonpath and import it during your debugging session.

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] != '_'}

I've added an example session on pastebin

There are a couple of cases this misses. And you might want to extend it to allow you to pass in types too. But it should let you filter most everything but the variables you defined.

dir()

If you just want the last 20 values so you get output like >>> p var1 var2 ... varn would give you, then you're better off slicing dir() like dir()[-20:], but you won't easily see the relationship between the variables and values. eg: "Did I declare foo before or after bar?"

If you want to see that relationship, you can try something like this, which assumes that your variables are at the end of dir(). You can slice differently if they're at the beginning. This won't work well if your variables aren't contiguous.

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

这篇关于在使用pdb调试Python时,如何打印所有变量值,而不指定每个变量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆