Допустим, вы использовали frozendict
реализацию, такую как эту :
class frozendict(collections.Mapping):
"""
An immutable wrapper around dictionaries that implements the complete :py:class:`collections.Mapping`
interface. It can be used as a drop-in replacement for dictionaries where immutability is desired.
"""
dict_cls = dict
def __init__(self, *args, **kwargs):
self._dict = self.dict_cls(*args, **kwargs)
self._hash = None
def __getitem__(self, key):
return self._dict[key]
def __contains__(self, key):
return key in self._dict
def copy(self, **add_or_replace):
return self.__class__(self, **add_or_replace)
def __iter__(self):
return iter(self._dict)
def __len__(self):
return len(self._dict)
def __repr__(self):
return '<%s %r>' % (self.__class__.__name__, self._dict)
def __hash__(self):
if self._hash is None:
h = 0
for key, value in self._dict.items():
h ^= hash((key, value))
self._hash = h
return self._hash
Если вы хотите изменить ее, вы можете просто войти и изменить self._dict
:
d = frozendict({'a': 1, 'b': 2})
d['a'] = 3 # This fails
mutable_dict = d._dict
mutable_dict['a'] = 3 # This works
print(d['a'])
Это немного отвратительно, когда я захожу к защищенным ученикам, но я бы сказал, что все в порядке, потому что ты пытаешься сделать немного отвратительно.Если вы хотите непостоянный словарь (просто dict
), используйте его.Если вы никогда не хотите изменять его, используйте реализацию frozendict
, подобную приведенной выше.Гибрид изменчивого и неизменного не имеет смысла.Все, что делает frozendict
, - это то, что он не реализует методы мутации dunder (__setitem__
, __delitem__
и т. Д.).Под капотом frozendict
представляет собой обычный, изменчивый dict
.
Вышеупомянутый подход, на мой взгляд, превосходит тот, который вы связали.Композиционность (имеющая frozendict
со свойством _dict
) гораздо проще рассуждать, чем наследование (подкласс dict
) во многих случаях.