如何在Python中使字典只读

ssh*_*sky 24 python dictionary

我有一个类:

class A:
    def __init__(self):
        self.data = {}
Run Code Online (Sandbox Code Playgroud)

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

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

我试过这个:

a = A()
a.data = types.MappingProxyType(a.data)
Run Code Online (Sandbox Code Playgroud)

这应该工作,但首先,它的python3.3 +和第二,当我这样做"禁止"多次我得到这个:

>>> a.data = types.MappingProxyType(a.data)
>>> a.data = types.MappingProxyType(a.data)
>>> a.data
mappingproxy(mappingproxy({}))
Run Code Online (Sandbox Code Playgroud)

虽然如果mappingproxy({})我要"禁止"很多次,那会好得多.检查isinstance(MappingProxyType)是一个选项,但我认为可以存在其他选项.

谢谢

mou*_*uad 33

使用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)
Run Code Online (Sandbox Code Playgroud)

HTH,


Mar*_*ski 22

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

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__
Run Code Online (Sandbox Code Playgroud)

  • ``ro_dict = ReadOnlyDict(rw_dict)```` (4认同)

Jad*_*una 8

很简单,你只需覆盖默认的dict方法!
这是一个例子:

class ReadOnlyDict(dict):

    __readonly = False

    def readonly(self, allow=1):
        """Allow or deny modifying dictionary"""
        self.__readonly = bool(allow)

    def __setitem__(self, key, value):

        if self.__readonly:
            raise TypeError, "__setitem__ is not supported"
        return dict.__setitem__(self, key, value)

    def __delitem__(self, key):

        if self.__readonly:
            raise TypeError, "__delitem__ is not supported"
        return dict.__delitem__(self, key)
Run Code Online (Sandbox Code Playgroud)

顺便说一句,你也可以删除.pop,.update以及你需要的其他方法.只是玩弄它.

  • 这种方法很明显,但并不简单,因为我必须覆盖几乎每个`dict`方法,甚至重新实现`dict`视图,如`.keys()`,`.items()`等等.如果Guido添加了更多未来的python版本?无论如何,谢谢你的观点,但我希望有更多答案. (4认同)