3

Code goes first,

#Python 2.7

>>>class A(object):
       pass

>>>a1 = A()
>>>a2 = A()

>>>A.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'A' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})

Question

1.what is dict_proxy and why use it?

2.A.__dict__ contains an attr -- '__dict': <attribute '__dict__' of 'A' objects>. What is this? Is it for a1 and a2? But objects of A have their own __dict__, don't they?

Alcott
  • 17,905
  • 32
  • 116
  • 173

3 Answers3

4

For your fist question I quote from Fredrik Lundh: http://www.velocityreviews.com/forums/t359039-dictproxy-what-is-this.html:

a CPython implementation detail, used to protect an internal data structure used
by new-style objects from unexpected modifications.
Niek de Klein
  • 8,524
  • 20
  • 72
  • 143
2

For your second question:

>>> class A(object):
       pass

>>> a1 = A()
>>> a2 = A()
>>> a1.foo="spam"
>>> a1.__dict__
{'foo': 'spam'}
>>> A.bacon = 'delicious'
>>> a1.bacon
'delicious'
>>> a2.bacon
'delicious'
>>> a2.foo
Traceback (most recent call last):
  File "<pyshell#314>", line 1, in <module>
    a2.foo
AttributeError: 'A' object has no attribute 'foo'
>>> a1.__dict__
{'foo': 'spam'}
>>> A.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'A' objects>, 'bacon': 'delicious', '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'A' objects>, '__doc__': None})

Does this answer your question?

If not, dive deeper: https://stackoverflow.com/a/4877655/1324545

Community
  • 1
  • 1
ch3ka
  • 11,792
  • 4
  • 31
  • 28
  • I just wanna know, why `A.__dict__` still contains a `'__dict__': `, is this one for instances of `A`? – Alcott May 08 '12 at 12:24
  • 1
    yes, but it is not a `__dict__`. it *implements* `__dict__` for the instances. this is explained in the link I posted. – ch3ka May 08 '12 at 12:30
0

dict_proxy prevents you from creating new attributes on a class object by assigning them to the __dict__. If you want to do that use setattr(A, attribute_name, value).

a1 and a2 are instances of A and not class objects. They don't have the protection A has and you can assign using a1.__dict__['abc'] = 'xyz'

Anthon
  • 69,918
  • 32
  • 186
  • 246