如果类有 __dict__ 变量,可以检查 obj.__dict__ 吗?
我感兴趣的是是否有一种方法可以无误地内省 Python 实例以查看其 __dict__,尽管程序员可能会遇到任何障碍,因为这将帮助我调试诸如意外引用循环之类的问题以及悬空资源,例如打开的文件。
一个更简单的例子是:如果程序员将 keys()
隐藏在自己的类后面,我如何才能看到 dict
子类的键?解决方法是手动调用 dict
keys()
方法,而不是让继承调用该方法的子类版本:
# Simple example of getting to the real info
# about an instance
class KeyHidingDict(dict):
def keys(self):
return [] # there are no keys here!
khd = KeyHidingDict(a=1, b=2, c=3)
khd.keys() # drat, returns []
dict.keys(khd) # aha! returns ['a', 'b', 'c']
现在我的实际问题是,我怎样才能看到实例的 __dict__ ,无论程序员可能做了什么来向我隐藏它?如果他们设置了一个 __dict__ 类变量,那么它似乎会隐藏从该类继承的任何对象的实际 __dict__ :
# My actual question
class DunderDictHider(object):
__dict__ = {'fake': 'dict'}
ddh = DunderDictHider()
ddh.a = 1
ddh.b = 2
print ddh.a # prints out 1
print ddh.__dict__ # drat, prints {'fake': 'dict'}
这个 __dict__
的错误值确实正如您所看到的,不会干扰实际的属性设置和获取,但它确实通过隐藏 a
和 b
并显示来误导 dir()
fake
作为对象的实例变量 反而。
同样,我的目标是编写一个工具,当我想知道为什么一组类实例占用如此多的内存或打开如此多的文件时,可以帮助我内省类实例以了解“到底发生了什么” - 即使上面的情况是非常人为的,找到一种解决方法可以让该工具一直工作,而不是说“工作很好,除非您正在查看的类有......[上面特殊情况的描述]”。
我原以为我能够通过以下方式准确无误地获取 __dict__:
dict_descr = object.__dict__['__dict__']
print dict_descr(ddh, DunderDictHider)
但事实证明,object
没有 __dict__ 描述符。相反,subtype_dict()
C 函数似乎单独附加到程序员创建的 object
的每个子类;没有集中的方法来命名或获取描述符,以便可以将其手动应用于其类隐藏它的对象。
有什么想法吗? :)
I am interested in whether there is a way to introspect a Python instance infallibly to see its __dict__
despite any obstacles that the programmer might have thrown in the way, because that would help me debug problems like unintended reference loops and dangling resources like open files.
A simpler example is: how can I see the keys of a dict
subclass if the programmer has hidden keys()
behind a class of its own? The way around that is to manually call the dict
keys()
method instead of letting inheritance call the subclass's version of the method:
# Simple example of getting to the real info
# about an instance
class KeyHidingDict(dict):
def keys(self):
return [] # there are no keys here!
khd = KeyHidingDict(a=1, b=2, c=3)
khd.keys() # drat, returns []
dict.keys(khd) # aha! returns ['a', 'b', 'c']
Now my actual question is, how can I see the __dict__
of an instance, no matter what the programmer might have done to hide it from me? If they set a __dict__
class variable then it seems to shadow the actual __dict__
of any objects inherited from that class:
# My actual question
class DunderDictHider(object):
__dict__ = {'fake': 'dict'}
ddh = DunderDictHider()
ddh.a = 1
ddh.b = 2
print ddh.a # prints out 1
print ddh.__dict__ # drat, prints {'fake': 'dict'}
This false value for __dict__
does not, as you can see, interfere with actual attribute setting and getting, but it does mislead dir()
by hiding a
and b
and displaying fake
as the object's instance variable instead.
Again, my goal is to write a tool that helps me introspect class instances to see “what is really going on” when I am wondering why a set of class instances is taking so much memory or holding so many files open — and even though the situation above is extremely contrived, finding a way around it would let the tool work all the time instead of saying “works great, unless the class you are looking at has… [description of the exceptional situation above].”
I had thought I would be able to infallibly grab the __dict__
with something like:
dict_descr = object.__dict__['__dict__']
print dict_descr(ddh, DunderDictHider)
But it turns out that object
does not have a __dict__
descriptor. Instead, the subtype_dict()
C function seems to get separately attached to each subclass of object
that the programmer creates; there is no central way to name or fetch the descriptor so that it can be manually applied to objects whose class shadows it.
Any ideas, anyone? :)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不确定我对这有多简单感到满意:
问题是班级作弊?解决这个问题!
就是这样。但是,如果该类定义了任何插槽,则这完全失败。
I'm not sure I'm happy with how simple this is:
The problem is that the class is cheating? Fix that!
And there it is. This completely fails though, if the class defines any slots.
这是基于 Jerub 在本主题中的回答:
Python 中的元类是什么?
您可以实现您想要的目标与元类。
首先,您需要创建一个元类:
当然打印不是必需的。
然后让我介绍一下您的新 DunderDictHider:
现在您可以通过
repr(DunderDictHider)
访问所有初始化的元素输出(使用
print repr(DunderDictHider)
行):每次您可以尝试
知道这个类是否试图隐藏它的
__dict__
。请记住,repr 输出是一个字符串。它可以做得更好,但这就是想法本身。This one is based on Jerub answer in this topic:
What is a metaclass in Python?
You can achieve what you're looking for with metaclasses.
First you need to create a metaclass:
of course the prints are not necessery.
Then let me introduce your new DunderDictHider:
Now you have access to all initialized elems by
repr(DunderDictHider)
The output (with
print repr(DunderDictHider)
line):Each time you can try
to know whether this class tries to hide its
__dict__
or not. Remember, that repr output is a string. It can be done better, but that's the idea itself.