[Python-Dev] Why are class dictionaries not accessible?

Devin Jeanpierre jeanpierreda at gmail.com
Thu Jun 23 16:03:00 EDT 2016


On Thu, Jun 23, 2016 at 8:19 AM, Guido van Rossum <guido at python.org> wrote:
>
> It was a long time when I wrote this, but IIRC the breakage could express
> itself as a segfault or other C-level crash due to some internal state
> invariant of the type object being violated, not just an exception. The
> existence of ctypes notwithstanding, we take C-level crashes very seriously.
>

Big digression: one can still obtain the dict if they really want to, even
without using ctypes. I suppose don't actually mutate it unless you want to
segfault.

>>> import gc
>>> class A(object): pass
>>> type(A.__dict__)
<class 'mappingproxy'>
>>> type(gc.get_referents(A.__dict__)[0])
<class 'dict'>
>>> gc.get_referents(A.__dict__)[0]['abc'] = 1
>>> A.abc
1
>>>

(One can also get it right from A, but A can have other references, so
maybe that's less reliable.)

I think I wanted this at the time so I could better measure the sizes of
objects. sys.getsizeof(A.__dict__) is very different
from sys.getsizeof(gc.get_referents(A.__dict__)[0]), and also different
from sys.getsizeof(A). For example:

>>> import gc
>>> class A(object): pass
>>> sys.getsizeof(A); sys.getsizeof(A.__dict__);
sys.getsizeof(gc.get_referents(A.__dict__)[0])
976
48
288
>>> for i in range(10000): setattr(A, 'attr_%s' % i, i)
>>> sys.getsizeof(A); sys.getsizeof(A.__dict__);
sys.getsizeof(gc.get_referents(A.__dict__)[0])
976
48
393312

(Fortunately, if you want to walk the object graph to measure memory usage
per object type, you're probably going to be using gc.get_referents already
anyway, so this is just confirmation that you're getting what you want in
one corner case.)

-- Devin
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-dev/attachments/20160623/22204201/attachment.html>


More information about the Python-Dev mailing list