Как создать класс словарь?
Есть ли возможность к примеру создать класс Аdict, который бы работал, как словарь?
т.е. к примеру Adict[5] = 'test'
Сделать класс, экземпляры, которого будут словарями, сложности не составляет. Надо всего лишь наследоваться от класса dict. И я подумал, что аналогично можно создать и метакласс, экземпляры, которого будучи классами, тоже работали бы схожим образом, но я не понимаю от чего надо наследоваться и какие методы следует переопределять. Надо ли наследоваться от dict или метаклассы могут наследоваться только от type?
Я хоть немного двигаюсь в правильном направлении здесь?:
class ADictMeta(dict):
def __new__(cls, *args, **kwargs):
return super().__new__(cls, args, kwargs)
def __setitem__(self, key, value):
self.__dict__[key] = value
def __getitem__(self, item):
return self.__dict__[item]
class Adict(metaclass=ADictMeta):
pass
Заранее спасибо за помощь!
Ответы (1 шт):
Метакласс должен быть потомком типа type, по крайней мере, если вы хотите чтобы класс, созданный с таким метаклассом являлся именно классом, а не просто словарем.
А наследоваться от dict вообще не обязательно, если в качестве хранилища вы используете внутренний словарь класса.
class ADictMeta(type):
def __setitem__(self, key, value):
setattr(self, key, value)
def __getitem__(self, key):
return getattr(self, key)
class Adict(metaclass=ADictMeta):
pass
Adict['key'] = 'value'
print(Adict.key) # value
Если же нужно отдельное хранилище, то все равно лучше не наследоваться от dict, вряд ли множественное наследование здесь пройдет успешно. Для того, чтобы другие объекты воспринимали его как изменяемый словарь, достаточно чтобы он реализовал методы базового класса MutableMapping
class ADictMeta(type):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.mydict = {}
def __delitem__(self, key):
del self.mydict[key]
def __setitem__(self, key, value):
self.mydict[key] = value
def __getitem__(self, key):
return self.mydict[key]
def clear(self):
self.mydict.clear()
def pop(self, *args, **kwargs):
return self.mydict.pop(*args, **kwargs)
def popitem(self):
return self.mydict.popitem()
def setdefault(self, *args, **kwargs):
return self.mydict.setdefault(*args, **kwargs)
def update(self, *args, **kwargs):
self.mydict.update(*args, **kwargs)
def __contains__(self, key):
return key in self.mydict
def get(self, *args, **kwargs):
return self.mydict.get(*args, **kwargs)
def items(self):
return self.mydict.items()
def keys(self):
return self.mydict.keys()
def values(self):
return self.mydict.values()
def __len__(self):
return len(self.mydict)
def __iter__(self):
return iter(self.mydict)
class Adict(metaclass=ADictMeta):
pass
Adict['key'] = 'value'
print(dict(Adict)) # {'key': 'value'}
print({**Adict, 'key2': 'value2'}) # {'key': 'value', 'key2': 'value2'}