Following piece of code lists the attributes of a class named 'A' in a sorted order:-
>>> class A():
def __init__(self, i):
self.at = i
>>> sorted(vars(A))
['__dict__', '__doc__', '__init__', '__module__', '__weakref__']
Now, printing the value of key, '__dict__'
results this:-
>>> vars(A)['__dict__'] #Value of '__dict__'
<attribute '__dict__' of 'A' objects>
As per docs, vars([object])
Return the
__dict__
attribute for a module, class, instance, or any other object with a__dict__
attribute.
What I am not understanding is that is the '__dict__'
attribute in the list the same attribute used by vars()
to return the attributes of A
or is it a different attribute which has some another objective like implementing A's objects' namespace as suggested (according to me) by the value which '__dict__'
holds.
Edit:-
The first part of the question is very much related to this other question (also, mentioned by @eliotness) but it's the second part (described below) for which I can't find any answers or related question and hence, changing title of the question.
Let's consider another code that produces list of attributes of ultimate base class in Python, object
:-
>>> sorted(vars(object))
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', ...., '__str__', '__subclasshook__']
>>> hasattr(object, '__dict__')
True
>>> sorted(getattr(object, '__dict__')) == sorted(vars(object))
True
Another quotation from docs about object.__dict__
A dictionary or other mapping object used to store an object’s (writable) attributes.
This time, '__dict__'
doesn't show up in the list of object
. So, is it that the __dict__
attribute is a read-only attribute in case of object
or any other reason?
Also, is it possible to get a list of read-only attributes in Python in any way?
This returns the __dict__ attribute of obj, which contains all the attributes of the object which can be writable. Here, obj can be any module / class / instance of a class, etc. There are a couple of cases here, depending on the argument type and the number of arguments too.
The dir () function is used to list the attributes available for the objects. The ‘ dir ’ takes into consideration the instances, it’s class and inherited classes. __ dict __ only contains the local attributes of the object. To get the class attributes __ dict __ can be used on class Fruit.
What is ‘ __dict__ ’ in Python? Python uses a special built-in attribute __dict__ to store object’s mutable attributes. Basically ‘__dict__’ is a dictionary with a key/value pair of object’s attributes. The ‘ __dict__ ’ attribute is not just limited to instances but can also be available to user-defined functions, modules, ...
Python Class - Get dictionary of class instance (__dict__ and vars) Python class instance has __dict__ method. We can get the dictionary of class instance attributes as follow. class Employee: def __init__(self, name, age): self.name = name self.age = age def hello(self): print ("I'm " + self.name + "."
The first part of your question is already answered by the linked answer: the __dict__
of instances is stored as a descriptor on the class. This is the A.__dict__['__dict__']
. A.__dict__
on the other hand stores all the attributes of the A
class - which itself is an instance of type
. So actually it's type.__dict__['__dict__']
that provides these variables:
>>> type.__dict__['__dict__']
<attribute '__dict__' of 'type' objects>
>>> A.__dict__ == type.__dict__['__dict__'].__get__(A)
True
The reason why you're not seeing a __dict__
attribute on object
is because it doesn't have one. This means you can't set instance variables on object
instances:
>>> o = object()
>>> o.x = 1
AttributeError: 'object' object has no attribute 'x'
Similar behavior can be achieved for custom classes by defining __slots__
:
>>> class B:
... __slots__ = ()
...
>>> vars(B)
mappingproxy({'__module__': '__main__', '__slots__': (), '__doc__': None})
>>>
>>> b = B()
>>> b.x = 1
AttributeError: 'B' object has no attribute 'x'
Firstly I want to say that I only partly know the answer to your question. The second part may not be entirely true on the behaviour of python. But first, I want to clear some things out: the docs you are quotings are concerning normal objects and may not apply on meta-classes as their internal behaviour is entirely coded in C.
As I understand how python works, I suspect the __dict__
you saw here:
>>> vars(A)['__dict__'] #Value of '__dict__'
<attribute '__dict__' of 'A' objects>
I suspect it to be a sample for the __dict__
attribute of a future instance of the class. I don't have better answer for now but let's keep digging.
__dict__
attribute on meta-classesAs object
is a of class type
is is pretty normal for it not to have a __dict__
as it is not possible to add attribute on basic types like int, float, or str. So why would these types have a __dict__
attribute if it is not used?
And finally, yes. There are restrictions on the __dict__
attribute of classes and meta-classes. These restrictions take form as the class MappingProxy like said in the vars
documentation:
Objects such as modules and instances have an updateable
__dict__
attribute; however, other objects may have write restrictions on their__dict__
attributes (for example, classes use a types.MappingProxyType to prevent direct dictionary updates).
But this behaviour is also explicitly said in the doc of the class object
Edit: I started to find good information about the wierd vars(A)['__dict__']
. Take a look here
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With