具有keyobject对的不可变字典Python

2024-06-16 10:50:18 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一本字典,里面装满了键-对象对。我想使字典不可变,我认为最好/最简单的方法是将其转换为冻结集,但frozenset(dict)和{}只存储键。在

使用frozenset(dict.items())我似乎得到了一个包含键-对象对的冻结集,但我不知道如何检索值/键。在

我有下面的代码,只要“\uuufuscators”是一个字典

def obfuscate_value(self, key, value):
    obfuscator = self.__obfuscators.get(key)
    if obfuscator is not None:
        return obfuscator.obfuscate_value(value)
    else:
        return value

我试着让它和冷冻装置一起工作:

^{pr2}$

但这就产生了{} 并且self.__obfuscators.__getattribute__(key)总是说它没有属性(因为我假设它搜索一个名为key的函数) 有没有更好的方法使字典不可变,或者如何根据键检索对象?在

编辑: 最后我使用tuple(obfuscator.items())将dict转换为元组 然后写了我自己的find value函数:

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

我要感谢大家的努力和投入。在


Tags: 对象方法keyselfreturnif字典value
3条回答

可以使用^{}创建字典的不可变视图:

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

请注意,您仍然可以更改vaule对象,因此:

^{pr2}$

会有用的。在

我能想到的实现您想要的最简单的方法是子类化标准dict类型并重写其__setitem__方法:

class MyDict(dict):
    def __setitem__(self, key, value):
        raise NotImplementedError("This is a frozen dictionary")

这允许您创建以后不能通过项目分配更改的词典:

^{pr2}$

或者,相当于:

d = MyDict([(1, 2), (3, 4)])

然后,dict会像标准dict一样打印出来:

{1: 2, 3: 4}

但当您尝试更改值(或添加新值)时:

d[1] = 15
---------------------------------------------------------------------------
NotImplementedError                       Traceback (most recent call last)
<ipython-input-21-a22420992053> in <module>()
----> 1 d[1] = 34

<ipython-input-18-03f266502231> in __setitem__(self, key, value)
      1 class MyDict(dict):
      2     def __setitem__(self, key, value):
----> 3         raise NotImplementedError("This is a frozen dictionary")

NotImplementedError: This is a frozen dictionary

但是请注意,这并不是完全不变的:

d.update({1:17})

例如,将更新它,但是这个解决方案可能已经足够好了-它取决于更广泛的需求。在

您可以创建一个包装类,该类接受字典并具有get item函数,但没有set item。您可能需要为线程安全性和哈希添加一些东西,但是基本类不会太难。在

相关问题 更多 >