虽然frozendict
被拒绝了,但是types.MappingProxyType
在python 3.3中向公共API添加了一个相关的类.
我理解MappingProxyType
的只是底层的一个包装dict
,但尽管它在功能上并不等同于frozendict
?
换句话说,原始PEP 416 frozendict
与此之间的实质区别是什么:
from types import MappingProxyType def frozendict(*args, **kwargs): return MappingProxyType(dict(*args, **kwargs))
当然MappingProxyType
不是像现在这样可以清洗,但正如PEP所建议的那样frozendict
,它可以在确保其所有值都是可清除之后可以使用(MappingProxyType不能被子类化,因此需要组合和转发方法).
MappingProxyType
是用于映射(例如dict)对象的只读代理.
frozendict
是一个不可改变的词典
代理模式是(引用维基百科):
代理以其最一般的形式,是一个充当其他东西的接口的类.
这MappingProxyType
只是一个访问真实对象的简单代理(即接口)(真实地图,在我们的例子中是dict).
建议的frozendict
对象就像冻结集一样.只读(不可变)对象,只能在创建时更改.
那么我们为什么需要MappingProxyType
呢?示例用例是您希望将字典传递给另一个函数但没有它能够更改字典的情况,它充当只读代理,(引用python文档):
映射的只读代理.它提供了映射条目的动态视图,这意味着当映射发生更改时,视图会反映这些更改.
让我们看看一些示例用法 MappingProxyType
In [1]: from types import MappingProxyType In [2]: d = {'a': 1, 'b': 2} In [3]: m = MappingProxyType(d) In [4]: m['a'] Out[4]: 1 In [5]: m['a'] = 5 TypeError: 'mappingproxy' object does not support item assignment In [6]: d['a'] = 42 In [7]: m['a'] Out[7]: 42 In [8]: for i in m.items(): ...: print(i) ('a', 42) ('b', 2)
因为PEP没有进入python,我们无法确定实现的是什么.通过观察PEP,我们看到:
frozendict({'a': {'b': 1}})
会引发一个异常,因为{'b': 1}
它不是可缓存的值,但是在你的实现它会创建对象.当然,您可以按照PEP中的说明添加值的验证.
我假设PEP的一部分是内存优化,并且这种冻结的实现可以从使用该__hash__
实现的dict比较的性能中受益.