Python interaction between __setattr__ and self .__ dict__

If I create such an instance of a class

class MyClass(object): pass x = MyClass() 

Then I can set the attributes to x as follows:

x.myAttr = 1 or x.__setattr__('myAttr', 1)

However, if I do a dict

 d = {} 

I cannot set attributes on it. For example, if I do this

 d.__setattr__('myAttr', 1) 

I get the error "'dict' object does not have attribute 'myAttr' 'The same thing happens if I try

 d.myAttr = 1 

I noticed that in the case of x.myAttr = 1, what actually happens is that

 x.__dict__ 

updated with a new key, so it should be that

 d.__setattr__ 

doesn't work because d doesn't have

 d.__dict__ 

simply because d is a dict. I would really appreciate it if someone could explain in detail what is happening here.

Do all python objects have .__dict__ ?

Why d.__setattr__ my attempt to call d.__setattr__ result in an error saying that the attribute does not exist?

Is there a specific hierarchy of built-in types that I should be aware of? A simple link would be greatly appreciated.

python 2.6.4

Windows XP Pro x64 SP2

+4
source share
5 answers

A dict instance does not have the __dict__ attribute, so you cannot assign attributes to it. Most Python built-in classes (which are written in C and define attributes differently) do not. If you are a subclass of dict , the subclass will have the __dict__ attribute, and you can then add the attributes to the instances of the subclass.

+4
source

copy-paste from docs.python.org:

The special attribute of each module is __dict__. This is a dictionary containing a module symbol table. Changing this dictionary will actually change the module symbol table, but direct assignment of the __dict__ attribute is not possible (you can write m .__ dict __ ['a'] = 1, which defines ma as 1, but you cannot write m .__ dict__ = {}). It is not recommended to change the __dict__ parameter.

http://docs.python.org/library/stdtypes.html

Method

Both lines do the same:

 x.__setattr__('a', b) xa = b 

How __ add__ is:

 x.__add__(b) x + b 

However, you can override the dict .__ setattr__ function to make you want

edit for 3rd comment:

 class x(object): def __init__(self): pass def __setattr__(self, a, b): print "nope, i will not set the attribute %s = %s" % (a,b) c = x() ca = 4 print c.__dict__ 

will print "no, I will not set the attribute a = 4 and c.__dict__ will not have the attribute 'a'

+3
source

Explanation of exception:

 >>> class C(object): ... __slots__ = ('a', 'b') ... >>> c = C() >>> ca = 1 >>> ct = 2 Traceback (most recent call last): File "<input>", line 1, in <module> AttributeError: 'C' object has no attribute 't' 

slots are described here

+1
source

self.__dict__ is a dict . Suppose dict also has __dict__ , its recursive definition and things will not work __dict__

0
source

If you do x.myAttr = 1 , you really do x.__dict__['myAttr'] = 1 . If you made x.__dict__.myAttr , you will get the same error as with d.myAttr . Destination. attribute defined for classes, but not dicts - assigning a dict instead of d['attribute'] .

0
source

Source: https://habr.com/ru/post/1416196/


All Articles