Q:

Python interaction between __setattr__ and self.__dict__

If I make a class instance like this
class MyClass(object):
    pass
x = MyClass()

I can then set attributes on x as follows:
x.myAttr = 1 or x.__setattr__('myAttr', 1)
However, if I make 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 has no attribute 'myAttr' " The same thing happens if I try
d.myAttr = 1

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

gets updated with a new key, so it must be that
d.__setattr__

doesn't work because d doesn't have
d.__dict__

simply because d is a dict. I would appreciate it very much if someone could thoroughly explain what's going on here.
Do all python objects have .__dict__?
Why does my attempt at calling d.__setattr__ result in an error saying that the attribute doesn't exist?
Is there a specific heirarchy of built-in types that I should know about? A simple reference would be much appreciated.
python 2.6.4
Windows XP Pro x64 SP2

A:

A dict instance doesn't have a __dict__ attribute, so you can't assign attributes on it. Most of Python's built-in classes (which are written in C and define attributes differently) don't. If you subclass dict, the subclass will have a __dict__ attribute and you can then add attributes to instances of the subclass.

A:

copy-paste from docs.python.org:

A special attribute of every module is __dict__. This is the dictionary
  containing the  module’s symbol table. Modifying this dictionary will
  actually change the module’s symbol table, but direct assignment to the
  __dict__ attribute is not possible (you can write m.__ dict__['a'] = 1,
  which defines m.a to be 1, but you can’t write  m.__dict__ = {}).
  Modifying __dict__ directly is not recommended.

http://docs.python.org/library/stdtypes.html
The method
Both lines do the same:
x.__setattr__('a', b)
x.a = b

Like __ add__ is:
x.__add__(b)
x + b

However, you can redefine a dict.__ setattr__ function to whatever 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()
c.a = 4
print c.__dict__

will print "nope, i will not set the attribute a = 4
and c.__dict__ won't have the attribute 'a'

