如何使字典只读?

新手上路,请多包涵

我有一个类:

 class A:
    def __init__(self):
        self.data = {}

在某些时候我想禁止 self.data 字段修改。

我在 PEP-416 拒绝通知 中读到有很多方法可以做到这一点。所以我想找到它们是什么。

我试过这个:

 a = A()
a.data = types.MappingProxyType(a.data)

这应该有效,但首先,它是 python3.3+,其次,当我多次执行此“禁止”时,我得到了这个:

 >>> a.data = types.MappingProxyType(a.data)
>>> a.data = types.MappingProxyType(a.data)
>>> a.data
mappingproxy(mappingproxy({}))

尽管只获得 mappingproxy({}) 会好得多,因为我要“禁止”很多次。检查 isinstance(MappingProxyType) 是一个选项,但我认为可以存在其他选项。

谢谢

原文由 sshilovsky 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 622
2 个回答

使用 collections.Mapping 例如

import collections

class DictWrapper(collections.Mapping):

    def __init__(self, data):
        self._data = data

    def __getitem__(self, key):
        return self._data[key]

    def __len__(self):
        return len(self._data)

    def __iter__(self):
        return iter(self._data)

原文由 mouad 发布,翻译遵循 CC BY-SA 4.0 许可协议

这是快速(浅)只读字典的完整实现:

 def _readonly(self, *args, **kwargs):
    raise RuntimeError("Cannot modify ReadOnlyDict")

class ReadOnlyDict(dict):
    __setitem__ = _readonly
    __delitem__ = _readonly
    pop = _readonly
    popitem = _readonly
    clear = _readonly
    update = _readonly
    setdefault = _readonly

我之前的(更糟糕的)实现如下(感谢@mtraceur 的精彩评论!):

 class ReadOnlyDict(dict):
    def __readonly__(self, *args, **kwargs):
        raise RuntimeError("Cannot modify ReadOnlyDict")
    __setitem__ = __readonly__
    __delitem__ = __readonly__
    pop = __readonly__
    popitem = __readonly__
    clear = __readonly__
    update = __readonly__
    setdefault = __readonly__
    del __readonly__

原文由 Marcin Raczyński 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题