python3中的低级内省?

时间:2017-02-27 23:52:48

标签: python python-3.x introspection

是否有一些内省方法可以可靠地获取对象实例的基础数据结构,不受任何自定义的影响?

在Python 3中,对象的低级实现可能会被深深掩盖:属性查找可以自定义,甚至__dict____slots__属性也可能无法提供完整的图片,因为它们是可写的。 dir()明确表示显示“有趣”属性而非实际属性,甚至inspect模块似乎也不提供此类功能。

2 个答案:

答案 0 :(得分:4)

没有什么是完全通用的,特别是对于用 C 实现的对象。Python 类型只是没有为通用解决方案存储足够的实例布局元数据。也就是说,即使面对非常奇怪的 Python 级修改(包括删除或隐藏的插槽描述符以及删除或隐藏的 __dict__ 描述符),gc.get_referents 也非常可靠。

gc.get_referents 会给所有引用一个对象报告给垃圾收集系统。它不会告诉你为什么一个对象有一个特定的引用——它不会告诉你一个 dict 是 __dict__ 一个 dict 是一个不相关的插槽,碰巧有一个输入它。

例如:

import gc

class Foo:
    __slots__ = ('__dict__', 'a', 'b')
    __dict__ = None
    def __init__(self):
        self.x = 1
        self.a = 2
        self.b = 3

x = Foo()
del Foo.a
del Foo.b

print(gc.get_referents(x))

for name in '__dict__', 'x', 'a', 'b':
    try:
        print(name, object.__getattribute__(x, name))
    except AttributeError:
        print('object.__getattribute__ could not look up', name)

这个打印

[2, 3, {'x': 1}, <class '__main__.Foo'>]
__dict__ None
x 1
object.__getattribute__ could not look up a
object.__getattribute__ could not look up b

gc.get_referents 设法检索真实的实例字典以及 ab 槽,即使相关的描述符都丢失了。不幸的是,它没有提供有关它检索到的任何引用的含义的信息。

object.__getattribute__ 无法检索实例字典或 ab 槽。它确实设法找到x,因为它在检索其他属性时不依赖于__dict__描述符来查找实例字典,但是您需要已经知道{{ 1}} 是您应该查找的名称 - x 无法发现您应该在此对象上查找哪些名称。

答案 1 :(得分:0)

user202729 在评论中建议使用 object.__getattribute__(obj, "field")

围绕此构建自定义函数(使用 object.__getattribute__(obj,"__dict__")object.__getattribute__(obj,"__slots__"))似乎符合我将内部数据转储到文档稀疏的代码上的初衷。

然而,也有人指出,事情可能会更加混乱,或者对于用 C 实现的类来说是不可访问的。