使用pdb调试python脚本时,有没有获取详细对象信息的方法?
Is there any method of getting detailed object information when using pdb to debug python script?
我正在使用 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>
我想查看File对象的详细信息f
,但我只能得到它的地址。使用pdb
调试python
脚本时,有没有获取详细对象信息的方法?
您可以在 pdb 中使用大多数任意 Python 表达式。
我不知道 "detailed object information" 你在找什么,但一般来说,任何有用的东西都是一个属性。
因为你知道你有什么类型(file
),而且它是 Python 附带的内置或标准库类型,你可以 look it up in the docs 看看有什么属性它保证有。例如,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)]
正如文档在顶部附近解释的那样:
The getmembers()
function retrieves the members of an object such as a class or module. The sixteen functions whose names begin with “is” are mainly provided as convenient choices for the second argument to getmembers()
.
但这16个函数你不一定要用,你想传什么就传什么。正如 getmembers
文档所说:
Return all the members of an object in a list of (name, value) pairs sorted by name. If the optional predicate argument is supplied, only members for which the predicate returns a true value are included.
因此,作为示例,我编写了一个自定义函数 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...)
据我所知,最简单的方法是在 .pdbrc
文件中定义别名。
您可以在其中找到 pi
别名("print instance" 的缩写),它几乎可以满足您的需求。
那里还有其他有用的别名。
非常有用,强烈推荐。
我正在使用 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>
我想查看File对象的详细信息f
,但我只能得到它的地址。使用pdb
调试python
脚本时,有没有获取详细对象信息的方法?
您可以在 pdb 中使用大多数任意 Python 表达式。
我不知道 "detailed object information" 你在找什么,但一般来说,任何有用的东西都是一个属性。
因为你知道你有什么类型(file
),而且它是 Python 附带的内置或标准库类型,你可以 look it up in the docs 看看有什么属性它保证有。例如,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)]
正如文档在顶部附近解释的那样:
The
getmembers()
function retrieves the members of an object such as a class or module. The sixteen functions whose names begin with “is” are mainly provided as convenient choices for the second argument togetmembers()
.
但这16个函数你不一定要用,你想传什么就传什么。正如 getmembers
文档所说:
Return all the members of an object in a list of (name, value) pairs sorted by name. If the optional predicate argument is supplied, only members for which the predicate returns a true value are included.
因此,作为示例,我编写了一个自定义函数 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...)
据我所知,最简单的方法是在 .pdbrc
文件中定义别名。
您可以在其中找到 pi
别名("print instance" 的缩写),它几乎可以满足您的需求。
那里还有其他有用的别名。
非常有用,强烈推荐。