Python 具有键对象对的不可变字典
我有一本充满关键对象对的字典。我想使字典不可变,我认为最好/最简单的方法是将其强制转换为冻结集,但Python 具有键对象对的不可变字典,python,python-2.7,dictionary,frozenset,Python,Python 2.7,Dictionary,Frozenset,我有一本充满关键对象对的字典。我想使字典不可变,我认为最好/最简单的方法是将其强制转换为冻结集,但冻结集(dict)和元组(dict)只存储键 使用frozenset(dict.items())我似乎得到了一个带有键对象对的frozenset,但我不知道如何检索值/键 我有以下代码,只要“\uuuufuscators”是一个字典,它就可以工作 def obfuscate_value(self, key, value): obfuscator = self.__obfuscators.ge
冻结集(dict)
和元组(dict)
只存储键
使用frozenset(dict.items())
我似乎得到了一个带有键对象对的frozenset,但我不知道如何检索值/键
我有以下代码,只要“\uuuufuscators”是一个字典,它就可以工作
def obfuscate_value(self, key, value):
obfuscator = self.__obfuscators.get(key)
if obfuscator is not None:
return obfuscator.obfuscate_value(value)
else:
return value
我尝试了这个,试图让它与冻结集一起工作:
def obfuscate_value(self, key, value):
try:
obfuscator = self.__obfuscators[key]
except:
return value
return obfuscator.obfuscate_value(value)
但是这使得frozenset没有\\uu getitem \
和self.\uuuuu模糊器。\uuuuu getattribute\uuuuuu(key)
总是说它没有该属性(因为我假设它搜索名为key的函数)
有没有更好的方法使字典不可变,或者如何根据键检索对象
编辑:
最后,我使用tuple(obfuscator.items())将dict转换为一个tuple
然后编写了我自己的查找值函数:
def find_obfuscator(self, key):
for item in self.__obfuscators:
x, y = item
if self.case_insensitive:
if x.lower() == key.lower():
return y
else:
if x == key:
return y
我要感谢大家的努力和投入。您可以创建一个包装器类,该类使用字典并具有get item函数,但没有set item。您可能需要为线程安全和哈希添加一些东西,但基本类不会太难。我能想到的实现您想要的功能的最简单方法是对标准
dict
类型进行子类化,并覆盖其\u setitem\u
方法:
class MyDict(dict):
def __setitem__(self, key, value):
raise NotImplementedError("This is a frozen dictionary")
这允许您创建此后无法通过项目分配更改的词典:
d = MyDict({1: 2, 3: 4})
或者,相当于:
d = MyDict([(1, 2), (3, 4)])
然后,dict像标准dict一样打印出来:
{1: 2, 3: 4}
但当您尝试更改值(或添加新值)时:
例如,将对其进行更新,但此解决方案可能足够好-它取决于更广泛的需求。您可以使用以下方法创建字典的不变视图:
将起作用。既然您在原始帖子中提到了
tuple(dict)
,那么实现您想要的可能最简单的解决方案就是:
tuple(dict.items())
您需要一个能够冻结的
dict
?您只需制作一个:
class FrozenDict(dict):
def __init__(self, *args, **kwargs):
self._frozen = False
dict.__init__(self, *args, **kwargs)
def freeze(self):
self._frozen = True
def __setitem__(self, key, value):
if (self._frozen):
raise TypeError("Attempted assignment to a frozen dict")
else:
return dict.__setitem__(self, key, value)
a = FrozenDict({7:8})
a[5] = 6
print(a)
a.freeze()
a[3] = 2 # raises TypeError
在您调用
.freeze()
之前,它的行为将与通常的dict
完全相同。然后它被冻结。如何子类化collections.Mapping
或使用Mappingproxy
。据我所知,两者都是不可变的(对于给定的不可变值)。这是否回答了你的问题?我确实考虑过这个问题,但我希望有一个比创建自己的自定义字典类更简单/更快的解决方案。特别是因为我现在看起来很接近,因为我有一个带有键对象对的冻结集,但我无法访问它们,或者至少我不知道如何使用此选项,我仍然面临与冻结集(dict.items())
相同的问题。如何根据键访问值?当再次考虑此选项时,我意识到如果我创建自己的搜索功能,那么它可能是更容易的解决方案,因为所有其他选项都不简单
from types import MappingProxyType
d = { 'a': 1 }
fd = MappingProxyType(d)
fd['a']
#output:
1
fd['a'] = 2
#output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment
d = { 'a': [1] }
fd = MappingProxyType(d)
fd['a'].append(2)
fd['a']
#output:
[1,2]
tuple(dict.items())
class FrozenDict(dict):
def __init__(self, *args, **kwargs):
self._frozen = False
dict.__init__(self, *args, **kwargs)
def freeze(self):
self._frozen = True
def __setitem__(self, key, value):
if (self._frozen):
raise TypeError("Attempted assignment to a frozen dict")
else:
return dict.__setitem__(self, key, value)
a = FrozenDict({7:8})
a[5] = 6
print(a)
a.freeze()
a[3] = 2 # raises TypeError