なぜクラス__dict__
はmappingproxy
ですが、インスタンス__dict__
は単なるdict
です
>>> class A:
... pass
>>> a = A()
>>> type(a.__dict__)
<class 'dict'>
>>> type(A.__dict__)
<class 'mappingproxy'>
これにより、インタープリターは、クラスレベルの属性とメソッドのキーが文字列にしかできないことを保証できます。
他の場所では、Pythonは「同意する大人の言語」であり、オブジェクトの辞書はユーザーによって公開され、変更可能です。ただし、クラスレベルの属性およびクラスのメソッドの場合、キーが文字列であることを保証できるので、クラスレベルでの属性およびメソッド検索の一般的なケースコードを簡素化および高速化できます。特に、新しいスタイルのクラスの__mro__検索ロジックは、クラスdictキーは文字列です。
Mappingproxyは、__setattr__
メソッドを持たない単なる辞書です。
このコードをチェックアウトして参照できます。
from types import MappingProxyType
d={'key': "value"}
m = MappingProxyType(d)
print(type(m)) # <class 'mappingproxy'>
m['key']='new' #TypeError: 'mappingproxy' object does not support item assignment
mappingproxyは、Python 3.3です。次のコードは、dictタイプを示しています。
class C:pass
ci=C()
print(type(C.__dict__)) #<class 'mappingproxy'>
print(type(ci.__dict__)) #<class 'dict'>