兔奔的笔记1

时间:2021-02-01 19:29:40

如何用Python实现一个不可修改的字典

  • 继承collections的UserDict
  • 重写可以修改字典键值的方法,并抛出异常

import collections


class ImmutableDict(collections.UserDict):
def __init__(self, *args, **kwargs):
super(ImmutableDict, self).__init__(*args, **kwargs)

def __setitem__(self, key, value):
if key in self.keys():
raise TypeError('Fuck! Immutable dict!')
else:
self.data[key] = value

def __delitem__(self, key):
if key in self.keys():
raise TypeError('Fuck! Immutable dict!')
else:
raise KeyError


UserDict类的源码:
class UserDict(MutableMapping):
# Start by filling-out the abstract methods
def __init__(*args, **kwargs):
if not args:
raise TypeError("descriptor '__init__' of 'UserDict' object "
"needs an argument")
self, *args = args
if len(args) > 1:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
if args:
dict = args[0]
elif 'dict' in kwargs:
dict = kwargs.pop('dict')
import warnings
warnings.warn("Passing 'dict' as keyword argument is deprecated",
DeprecationWarning, stacklevel=2)
else:
dict = None
self.data = {}
if dict is not None:
self.update(dict)
if len(kwargs):
self.update(kwargs)
def __len__(self): return len(self.data)
def __getitem__(self, key):
if key in self.data:
return self.data[key]
if hasattr(self.__class__, "__missing__"):
return self.__class__.__missing__(self, key)
raise KeyError(key)
def __setitem__(self, key, item): self.data[key] = item
def __delitem__(self, key): del self.data[key]
def __iter__(self):
return iter(self.data)

# Modify __contains__ to work correctly when __missing__ is present
def __contains__(self, key):
return key in self.data

# Now, add the methods in dicts but not in MutableMapping
def __repr__(self): return repr(self.data)
def copy(self):
if self.__class__ is UserDict:
return UserDict(self.data.copy())
import copy
data = self.data
try:
self.data = {}
c = copy.copy(self)
finally:
self.data = data
c.update(self)
return c
@classmethod
def fromkeys(cls, iterable, value=None):
d = cls()
for key in iterable:
d[key] = value
return d