Python 不可变字典的可变包装器

Python 不可变字典的可变包装器,python,dictionary,memory,immutability,python-3.7,Python,Dictionary,Memory,Immutability,Python 3.7,问题就在这里;我有一本不可变的字典,里面有大量的条目。此dict中包含的键类型和值类型本身是不可变的。我希望能够变异这个dict(添加/删除/替换键值对),而不必做dict的完整副本 我正在为依附于dict契约的不可变dict设想一些包装器类,并为尚未更新的值默认为不可变dict。我看到了我计划用来制作这个包装器的帖子 在我开始实现这个设计之前,我只想问一个问题——这个构造已经由语言提供了吗?或者我怎样才能达到预期的效果?我使用的是最新版本的Python(3.7),因此我可以使用所有可用的语言功

问题就在这里;我有一本不可变的字典,里面有大量的条目。此dict中包含的键类型和值类型本身是不可变的。我希望能够变异这个dict(添加/删除/替换键值对),而不必做dict的完整副本

我正在为依附于dict契约的不可变dict设想一些包装器类,并为尚未更新的值默认为不可变dict。我看到了我计划用来制作这个包装器的帖子


在我开始实现这个设计之前,我只想问一个问题——这个构造已经由语言提供了吗?或者我怎样才能达到预期的效果?我使用的是最新版本的Python(3.7),因此我可以使用所有可用的语言功能。谢谢

看看
集合.ChainMap
。它是一个围绕多个字典的包装器:所有写操作都会进入第一个字典,并按照映射的顺序搜索查找。所以我想你可以这样做:

modified_map = {}
mutable_map = collections.ChainMap(modified_map, huge_immutable_map)

查看
集合.ChainMap
。它是一个围绕多个字典的包装器:所有写操作都会进入第一个字典,并按照映射的顺序搜索查找。所以我想你可以这样做:

modified_map = {}
mutable_map = collections.ChainMap(modified_map, huge_immutable_map)

假设您使用了
frozendict
实现,如:

class frozendict(collections.Mapping):
"""
实现完整的:py:class:`collections.Mapping的字典周围的不可变包装器`
接口。在需要不变性的地方,它可以作为字典的替代品。
"""
dict_cls=dict
定义初始化(self,*args,**kwargs):
self.\u dict=self.dict\u cls(*args,**kwargs)
self.\u hash=None
def _u获取项目(自身,密钥):
返回自我。\u dict[键]
def___;包含_______;(自身,密钥):
在self中返回键。\u dict
def副本(自身,**添加或替换):
返回self.\uuuu类\uuuuu(self,**添加或替换)
定义(自我):
返回iter(自行记录)
定义(自我):
回程透镜(自身)
定义报告(自我):
返回“”%(self.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
定义散列(自我):
如果self.\u hash为无:
h=0
对于键,值在self.\u dict.items()中:
h^=散列((键,值))
self.\u hash=h
返回self.\u散列
如果你想变异它,你可以直接进入并变异自我

d=frozendict({'a':1,'b':2})
d['a']=3#这是失败的
可变目录=d.。\U目录
可变dict['a']=3#这是可行的
打印(d['a'])
接触一个类的受保护成员有点恶心,但我想说这没关系,因为你想做的有点恶心。如果你想要一个可变字典(只是一个
dict
),那么就使用一个。如果您永远不想对其进行变异,请使用类似上面的
frozendict
实现。可变和不可变的混合是没有意义的。frozendict所做的一切就是它没有实现突变邓德尔方法(
\uuuuu setitem\uuuuuu
\uuu delitem\uuuuu
等)。发动机罩下的一个
frozendict
由一个规则的、可变的
dict
表示


在我看来,上述方法优于您链接的方法。在许多情况下,组合性(具有
frozendict
具有
\u dict
属性)比继承性(子类化
dict
)更容易推理。

假设您使用了
frozendict
实现,如:

class frozendict(collections.Mapping):
"""
实现完整的:py:class:`collections.Mapping的字典周围的不可变包装器`
接口。在需要不变性的地方,它可以作为字典的替代品。
"""
dict_cls=dict
定义初始化(self,*args,**kwargs):
self.\u dict=self.dict\u cls(*args,**kwargs)
self.\u hash=None
def _u获取项目(自身,密钥):
返回自我。\u dict[键]
def___;包含_______;(自身,密钥):
在self中返回键。\u dict
def副本(自身,**添加或替换):
返回self.\uuuu类\uuuuu(self,**添加或替换)
定义(自我):
返回iter(自行记录)
定义(自我):
回程透镜(自身)
定义报告(自我):
返回“”%(self.\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu
定义散列(自我):
如果self.\u hash为无:
h=0
对于键,值在self.\u dict.items()中:
h^=散列((键,值))
self.\u hash=h
返回self.\u散列
如果你想变异它,你可以直接进入并变异自我

d=frozendict({'a':1,'b':2})
d['a']=3#这是失败的
可变目录=d.。\U目录
可变dict['a']=3#这是可行的
打印(d['a'])
接触一个类的受保护成员有点恶心,但我想说这没关系,因为你想做的有点恶心。如果你想要一个可变字典(只是一个
dict
),那么就使用一个。如果您永远不想对其进行变异,请使用类似上面的
frozendict
实现。可变和不可变的混合是没有意义的。frozendict所做的一切就是它没有实现突变邓德尔方法(
\uuuuu setitem\uuuuuu
\uuu delitem\uuuuu
等)。发动机罩下的一个
frozendict
由一个规则的、可变的
dict
表示


在我看来,上述方法优于您链接的方法。在许多情况下,组合性(拥有
frozendict
拥有
\u dict
属性)比继承性(子类化
dict
)更容易推理。

啊,我不确定我在最初的问题中是否清楚。我不想改变不可变的支持指令。它与其他代码共享。啊,我不确定我在最初的问题中是否清楚。我不想改变不变的支持规则,它是共享的