快速确认 Python 对象结构

好吧,这个问题确实比较蛋疼的一个问题,也是最近经常遇到的问题。具体的原因是这样的,最近使用了一个开源的库实现功能,实现方法是使用的回调方式。这样就出现了一个问题,回调过来的对象是什么格式的我并不知道具体细节。有人说,看看文档不就行了么,问题是这个项目他就没个详细文档。其实读代码也是可以解决这个问题的,但是实际上这是一个时间的工作,并且很容易会把自己也绕进去。那怎么办呢?别急,往下看。

  1. 直接 dir 输出属性

这个很简单了,直接 print dir(对象名) 就可以打印对象的属性名称了。不过这个得来回测试一下,不能一次性把所有的想要的都能得到。

  1. 利用 pdb 快速定位

pdb 是官方库中的 Python Debugger,使用方法也比较简单:在 Python 代码中 import pdb 库,然后在指定的位置添加一句:pdb.set_trace()。以我的代码为例,我需要了解 msg 的结构:

1
2
3
4
5
6
class StickyMaster(controller.Master):
......

def handle_request(self, msg):
pdb.set_trace()
......

然后正常执行这个程序,在执行到这句时,得到如下结果:

1
2
3
4
5
✗ python pdbtest.py
......
> pdbtest.py(63)handle_request()
-> if allow_check(msg) is False:
(Pdb)

是不是看起来很像 gdb 一类的工具?这个时候输入命令查看对象了,输入 h 可以查看帮助:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
(Pdb) h

Documented commands (type help <topic>):
========================================
EOF bt cont enable jump pp run unt
a c continue exit l q s until
alias cl d h list quit step up
args clear debug help n r tbreak w
b commands disable ignore next restart u whatis
break condition down j p return unalias where

Miscellaneous help topics:
==========================
exec pdb

Undocumented commands:
======================
retval rv

接下来查看下当前变量:

1
2
3
(Pdb) a
self = <__main__.StickyMaster instance at 0x107884128>
msg = <libmproxy.flow.Request instance at 0x1080d5680>

然后直接 dir 一下这个变量的属性名称,这个时候的好处是方便进行查看属性值:

1
2
3
4
(Pdb) dir(msg)
['__doc__', '__eq__', '__hash__', '__init__', '__module__', '_assemble', '_assemble_head', '_from_state', '_get_state', '_load_state', '_set_replay', 'anticache', 'anticomp', 'client_conn', 'close', 'constrain_encoding', 'content', 'copy', 'decode', 'encode', 'get_content_type', 'get_cookies', 'get_decoded_content', 'get_form_urlencoded', 'get_header_size', 'get_path_components', 'get_query', 'get_transmitted_size', 'get_url', 'headers', 'host', 'httpversion', 'ip', 'is_live', 'is_replay', 'method', 'path', 'port', 'replace', 'reply', 'rfile', 'scheme', 'set_form_urlencoded', 'set_live', 'set_path_components', 'set_query', 'set_url', 'size', 'ssl_setup_timestamp', 'stickyauth', 'stickycookie', 'tcp_setup_timestamp', 'timestamp_end', 'timestamp_start', 'wfile']
(Pdb) msg.path
'/'
  1. 借助工具直接确定

这里我使用的是 WingIDE,很简单方便。首先下个断点,然后运行下程序,结果如下图:

WingIDE

就是这么简单!