使用pdb调试python脚本时是否有获取详细对象信息的方法?

时间:2015-04-17 03:26:39

标签: python debugging pdb

我正在使用pdb来调试简单的python脚本:

#!/usr/bin/python

f = open("./hello.scala")
f.close()

调试流程如下:

[root@localhost ~]# python -m pdb test.py
> /root/test.py(3)<module>()
-> f = open("./hello.scala")
(Pdb) n
> /root/test.py(4)<module>()
-> f.close()
(Pdb) p f
<open file './hello.scala', mode 'r' at 0x7f4d69aae8a0>
(Pdb) pp f
<open file './hello.scala', mode 'r' at 0x7f4d69aae8a0>

我想检查文件对象f的详细信息,但我只能获取它的地址。使用pdb调试python脚本时,有没有获取详细对象信息的方法?

2 个答案:

答案 0 :(得分:1)

您可以在pdb中使用大多数任意Python表达式。

我不知道&#34;详细的对象信息&#34;你正在寻找,但总的来说,任何有用的东西都是属性。

既然你知道你有什么类型(file),并且它是Python附带的内置或stdlib类型,你可以look it up in the docs看看它是什么属性& #39;保证有。例如,file个对象具有closed属性;看到了:

(Pdb) p f.closed
True

如果您不知道自己需要哪些属性,可以使用inspect模块提供帮助。例如:

(Pdb) import inspect
(Pdb) p inspect.getmembers(f, lambda x: not callable(x))
[('__doc__', "file(name[, mode[, buffering]]) -> file object\n\nOpen a file.  The mode can be 'r', 'w' or 'a' for reading (default),\nwriting or appending.  The file will be created if it doesn't exist\nwhen opened for writing or appending; it will be truncated when\nopened for writing.  Add a 'b' to the mode for binary files.\nAdd a '+' to the mode to allow simultaneous reading and writing.\nIf the buffering argument is given, 0 means unbuffered, 1 means line\nbuffered, and larger numbers specify the buffer size.  The preferred way\nto open a file is with the builtin open() function.\nAdd a 'U' to mode to open the file for input with universal newline\nsupport.  Any line ending in the input file will be seen as a '\\n'\nin Python.  Also, a file so opened gains the attribute 'newlines';\nthe value for this attribute is one of None (no newline read yet),\n'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n\n'U' cannot be combined with 'w' or '+' mode.\n"), ('closed', True), ('encoding', None), ('errors', None), ('mode', 'r'), ('name', 'temp.xml'), ('newlines', None), ('softspace', 0)]

如果您希望打印得漂亮,只需使用pp命令代替p

(Pdb) pp inspect.getmembers(f, lambda x: not callable(x))
[('__doc__',
  "file(name[, mode[, buffering]]) -> file object\n\nOpen a file.  The mode can be 'r', 'w' or 'a' for reading (default),\nwriting or appending.  The file will be created if it doesn't exist\nwhen opened for writing or appending; it will be truncated when\nopened for writing.  Add a 'b' to the mode for binary files.\nAdd a '+' to the mode to allow simultaneous reading and writing.\nIf the buffering argument is given, 0 means unbuffered, 1 means line\nbuffered, and larger numbers specify the buffer size.  The preferred way\nto open a file is with the builtin open() function.\nAdd a 'U' to mode to open the file for input with universal newline\nsupport.  Any line ending in the input file will be seen as a '\\n'\nin Python.  Also, a file so opened gains the attribute 'newlines';\nthe value for this attribute is one of None (no newline read yet),\n'\\r', '\\n', '\\r\\n' or a tuple containing all the newline types seen.\n\n'U' cannot be combined with 'w' or '+' mode.\n"),
 ('closed', True),
 ('encoding', None),
 ('errors', None),
 ('mode', 'r'),
 ('name', 'temp.xml'),
 ('newlines', None),
 ('softspace', 0)]

随着文档在顶部附近解释:

  

getmembers()函数检索对象(例如类或模块)的成员。名称以“是”开头的16个函数主要作为getmembers()的第二个参数的方便选择。

但是你不必使用这16个功能,你可以传递你想要的任何东西。正如getmembers文档所说:

  

返回按名称排序的(名称,值)对列表中对象的所有成员。如果提供了可选的谓词参数,则仅包含谓词返回true值的成员。

因此,作为一个例子,我编写了一个自定义函数lambda x: not callable(x),这对于不可调用的成员来说是正确的。这意味着我不会获得close方法之类的内容,只需closed属性。

如果您不理解lambda,那么它就是在表达式中间定义简单函数的一种方法。它和我写的一样:

def my_function(x):
    return not callable(x)

...然后调用inspect.getmembers(f, my_function)


虽然我们正在研究它,但您可能需要查看IPython,它是默认Python交互模式的替代品。除此之外,它还为您提供Pdb内的标签完成(以及在正常的交互式会话中):

ipdb> n
--Return--
None
> /Users/abarnert/src/pt.py(2)<module>()
1     1 f = open('temp.txt')
----> 2 f.close()

ipdb> p f
<_io.TextIOWrapper name='temp.xml' mode='r' encoding='UTF-8'>
ipdb> p f.
f.buffer          f.fileno          f.newlines        f.seekable
f.close           f.flush           f.read            f.tell
f.closed          f.isatty          f.readable        f.truncate
f.detach          f.line_buffering  f.readline        f.writable
f.encoding        f.mode            f.readlines       f.write
f.errors          f.name            f.seek            f.writelines
ipdb> p f.

(很抱歉在该示例脚本中使用Python 3;我的Python 2.7正好在升级IPython的过程中......)

答案 1 :(得分:1)

我知道实现此目的的最简单方法是在.pdbrc文件中定义别名。

此处Ned's famous .pdbrc file

在其中,您可以找到pi别名(&#34;打印实例&#34;的缩写),它几乎可以满足您的需求。

还有其他有用的别名。

非常有用,强烈推荐。