Python类的__dict__无法更新

Python类的dict无法更新?

测试环境: Python2.7

1
2
3
4
5
6
>>> class O(object): pass
...
>>> O.__dict__['name'] = 'Finger'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'dictproxy' object does not support item assignment

答:是的, class的__dict__是只读的

1
2
3
4
5
>>> O.__dict__
dict_proxy({'__dict__': <attribute '__dict__' of 'O' objects>, '__module__': '__main__', '__weakref__': <attribute '__weakref__' of 'O' objects>, '__doc__': None})
>>> O.__dict__.items()
[('__dict__', <attribute '__dict__' of 'O' objects>), ('__module__', '__main__'), ('__weakref__', <attribute '__weakref__' of 'O' objects>), ('__doc__', None)]

可以看到O.__dict__ 是一个dictproxy对象,而不是一个dict

1
2
>>> dir(O.__dict__)
['__class__', '__cmp__', '__contains__', '__delattr__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'copy', 'get', 'has_key', 'items', 'iteritems', 'iterkeys', 'itervalues', 'keys', 'values']

我们dir(O.__dict__),发现它没有__setitem__方法

那么我们怎么改类设置属性呢?可以用setattr

1
2
3
4
>>> setattr(O, 'name', 'Finger')
>>> O.name
'Finger'
>>>

可能在测试的过程中你会发现,如果你采用Python经典继承(Old-Style Classes)看到的结果却是这样的:

1
2
3
4
5
>>> class O: pass
...
>>> O.__dict__['name'] = 'Finger'
>>> O.name
'Finger'

关于Python的Old-Style和New-Style Classes下次再探讨

注意:在Python3.x中不管是Old-Style还是New-Style Classes都是不允许对类的__dict__进行修改。因为不管哪种继承方式,它们都是mappingproxy对象

1
2
3
4
5
6
7
8
9
10
11
12
>>> class O: pass
...
>>> O.__dict__['name'] = 'Finger'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment
>>> class O(object): pass
...
>>> O.__dict__['name'] = 'Finger'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment
坚持原创技术分享,您的支持将鼓励我继续创作!