Tool to inspect Python objects without changing them
今天晚上,当我试图跟踪一个Python程序中的资源泄漏时,我突然想到现代的ORM使工作相当困难。事实上,当您开始检查对象的属性时,一个单独存在于没有子对象的内存中的对象会突然出现十几个关联的对象,因为,当然,每个属性取消引用都会调用一个描述符,该描述符会动态地获取额外的信息。
我甚至注意到,对一个特定对象执行一个简单的print操作,最终会执行数据库查询,并将更多的链接对象拖到内存中,这会破坏我一直在计算的小心引用计数,因为它的__repr__()是从几个相关对象中构建显示的名称。
有一些技术可以在不影响检测对象的情况下进行检测,如type(obj)和id(obj)和obj.__dict__。(但不打印__dict__,因为它调用了__repr__(),字典中的每个值!)是否有人将这几种"安全"的检查方法结合起来,在类似于python调试器的提示下,方便地检查和探索python对象图形,以便我能够看到这些文件在何处被打开,使我无法使用文件描述符?
本质上,我需要一个反海森堡的工具,以防止我的检查行为有任何副作用!
"检查"模块:
有一个答案建议我尝试使用inspect()模块,但它似乎会取消对所提供对象的每个属性的引用:
1 2 3 4 5 6 7 8
| import inspect
class Thing(object):
@property
def one(self):
print 'one() got called!'
return 1
t = Thing()
inspect.getmembers(t) |
此输出:
1 2 3 4 5
| one() got called!
[('__class__', <class '__main__.Thing'>),
('__delattr__', <method-wrapper '__delattr__'…),
…
('one', 1)] |
号
- 也许您可以展示一个您实际希望看到的输出的示例?
- 你能为这个问题找到一个可以接受的解决方案吗?
python 3.2现在为这类用例提供了inspect.getattr_static():http://docs.python.org/py3k/library/inspect静态获取属性
从docs页面顶部的源代码链接应该可以很容易地将该功能移植到早期版本(尽管要记住,作为3.x stdlib代码,它不是为处理旧样式类而构建的)。
但是,我不知道有任何现有的工具可以将这种技术与检查obj.__dict__结合起来,在不调用描述符的情况下导航整个对象图。
- 在我的例子中,这段代码实际上做了一些不必要的事情:它检查描述符,以便报告作为属性生成的属性的名称。但在我的例子中——想知道哪些对象保留了哪些其他对象存在——我实际上希望像属性这样的虚拟属性消失,因为根据定义,它们不会影响任何引用计数,除非您调用它们。我只想知道哪些相关对象的参考计数实际上增加了——我认为这将推动对__dict__的手动检查。
我不知道各种方法有多安全(这似乎完全取决于您的具体情况),但是inspect模块提供了大量的检查工具。
- 一个有趣的主意!但是由inspect支持的主要函数(getmembers()调用)似乎调用了给定对象上的每个描述符—请看我在问题后面附加的示例。
- @Brandoncraigrardes是的,我在2.x中找不到任何方法来解决这个问题,至少在python 3.x中可以找到一些东西。你提到想要"看到这些文件在哪里被打开,使我没有文件描述符?"你熟悉lsof对吗?你可以用lsof | grep python来查看它打开的文件。如果你对他们的名字有一些控制权,你可以用它来告诉你自己是什么让他们保持开放……