我不知道为什么一个类__dict__
是一个mappingproxy
,但是一个实例__dict__
只是一个普通的dict
>>> class A:
... pass
>>> a = A()
>>> type(a.__dict__)
<class 'dict'>
>>> type(A.__dict__)
<class 'mappingproxy'>
Answers:
这有助于解释器确保类级属性和方法的键只能是字符串。
在其他地方,Python是一种“成年人同意语言”,这意味着对象的指示由用户公开和可变。但是,对于类的类级属性和方法,如果可以保证键是字符串,则可以在类级简化和加快用于属性和方法查找的常见案例代码。尤其是,通过假定类dict键为字符串,可以简化和加快用于新型类的__mro__搜索逻辑。
type.__setattr__
(希望/可能是一个很小的集合)的人有关,因为您不能写__dict__
;您必须使用super()
。
gc.get_referents(FooClass.__dict__)[0]['__eq__'] = eqmethod
,则的实例FooClass
可能实际上未eqmethod
用于==
比较。
映射代理只是没有__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'>
因为Python 3.3mappingproxy
类型已改名为从dictproxy
。关于这个话题有一个有趣的讨论。
很难找到这种类型的文档,但是vars方法的文档对此进行了很好的描述(尽管有一段时间没有对此进行记录了):
对象(例如模块和实例)具有可更新的
__dict__
属性。但是,其他对象可能对其__dict__
属性具有写限制 (例如,类使用type.MappingProxyType来防止直接字典更新)。
如果您需要分配新的类属性,则可以使用setattr
。值得注意的是,mappingproxy
它不是JSON可序列化的,请查看该问题以了解原因。
这种类型的历史也很有趣:
Python 2.7: type(A.__dict__)
返回<type 'dict'>
为type(dict())
,并且可以通过分配新属性__dict__
,例如
A.__dict__['foo'] = 'bar'
。
Python 3.0-3.2: type(A.__dict__)
返回<class 'dict_proxy'>
,现在区别更加清楚了。尝试分配新的属性将给予TypeError
。有一个尝试添加dictproxy
作为公共内建类型。
<class 'mappingproxy'>
上述类型。
mappingproxy
将class.__dict__
其class.__setattr__
设为只读,以便仅作为设置类属性的途径,而正是该方法强制执行了limit。