The __dict__
of a type is a dictproxy
object that is read only. I want to know what's the purpose of it. Is it only for "don't allow modify builtin types"? I found a method that can walk around this. I know it's not a good idea to modify builtin types. But I am trying to modify cdef class
of Cython on fly.
I want to know are there any dangerous to modify the __dict__
of cdef class
this way?
Here is the code:
import gc
gc.get_referents(float.__dict__)[0]["square"] = lambda self: self*self
(3.14).square()
__dict__
is a namespace object that holds the classes attributes.There shouldn't be a problem modifying the dict object as long as you don't modify the
__dict__
itself:Example:
Python documentation [ LINK ]:
Attribute assignment updates the module’s namespace dictionary, e.g., m.x = 1 is equivalent to m.__dict__["x"] = 1.
so there should be no problem modifying objects of the dict.
Furthermore:
Since we can modify the attributes of a class the dict of a class is always Writable:
__dict__ | The namespace supporting arbitrary function attributes. | Writable
Note
It could be Cpython has a slightly diffrent implementation than pyhton but as i can read from the documentation its not mentioned.
The purpose of
dictproxy
(found in classes) is to allow for optimisations in the Python interpreter and to ensure its stability. See MartijnPieters comment below for details on the requirements for the optimisations, which apparently rely on the keys ofclass.__dict__
always being strings.dictproxy
also seems to play a role in protecting against certain instabilities in the interpreter. For more information on one such instability, see the bug report and bug fix discussed on python.org with the title Bypassing __dict__ readonlyness. If you don't use some kind of proxy mechanism, then the__dict__
can be written to. If it can be written, it can be deleted. In the bug report they discuss some scenarios in which the__dict__
could be deleted and caused the interpreter to crash.Note that this contrasts with class instances, which you can assign to directly or with
__setitem__()
:instance.__dict__['x'] = 1
Also, the instance
__dict__
can be deleted. If it is deleted, then it gets automatically re-created when attribute assignment is attempted:del instance.__dict__ instance.a = 1 instance.__dict__
Conclusion
So in sum,
dictproxy
allows classes to operate more optimally and makes the interpreter more stable.