Я изучаю классы на Python и пытаюсь создать свою собственную версию defaultdict из модуля collections. Вот что я пробовал: -
class Mydict(dict):
def __missing__(self, key):
self.key = []
return []
Вот результат работы интерактивной оболочки: -
>>> d = Mydict()
>>> d['x']
#outputs []
>>> d['x'].extend([1,2,3,4,5])
>>> print(d)
# Outputs {}
Не понимаю, почему он не хранит ключ x в объекте d? Что я скучаю?
Нужно назначить self[key] вместо self.key.






dict предназначен для пары ключ-значение и используйте update для добавления значений
>>> d = Mydict()
>>> d.update({ "a" : 1, "b" : 2 })
>>> d
{'a': 1, 'b': 2}
>>> d.update({ "c" : 3, "d" : 4 })
>>> d
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
>>>
Редактировать:
Чтобы вернуть сохраненное значение вместо нового списка:
In [143]: class Mydict(dict):
...: def __missing__(self, key):
...: self.__setitem__(key, [])
...: return self[key]
...:
In [144]: d = Mydict()
In [145]: d[2].extend([1, 2, 3])
In [146]: d[2]
Out[146]: [1, 2, 3]
dict использует __setitem__ для установки пар ключ-значение, поэтому вам нужно использовать это вместо установки атрибутов:
In [113]: class Mydict(dict):
...: def __missing__(self, key):
...: self.__setitem__(key, [])
...: return []
...:
In [114]: d = Mydict()
In [115]: d[1]
Out[115]: []
In [116]: d
Out[116]: {1: []}
FWIW, вы можете использовать d.__dict__ или vars(d), чтобы получить атрибуты, которые вы установили обычными способами:
In [117]: class Mydict(dict):
...: def __missing__(self, key):
...: self.__setattr__(key, 'foo')
...: self.__setitem__(key, 'bar')
...: return []
...:
In [118]: d = Mydict()
In [119]: d['x']
Out[119]: []
In [120]: d
Out[120]: {'x': 'bar'}
In [121]: vars(d)
Out[121]: {'x': 'foo'}
пробовал, работает, но частично. Я имею в виду d[2].extend([1,5,4,8,7,5]), а затем print(d[2]) печатает {2:[]}. Как получить отображение расширенного списка в ключе 2 ??
@ Gsbansal10 Вам нужно вернуть сохраненное значение вместо нового списка; проверьте мои правки.
Линия self.key = [] не делает того, что вы думаете. Вы хотите добавить элемент в dict, но на самом деле это создает новый атрибут экземпляра Mydict с именем key и присваивает ему значение []. Чтобы увидеть это
>>> d = Mydict()
>>> d['x']
[]
>>> d.key
[]
Это сделает то, что вы ожидаете:
class Mydict(dict):
def __missing__(self, key):
self.__setitem__(key,[])
return []
Вы создаете атрибут вместо пункт:
self.key = [] # attribute named key
self[key] = bar # item stored for key
Вы также не возвращаете список, хранящийся на self, а создаете и возвращаете список Другая:
return [] # return a new list
return self[key] # return the stored list
В вашем методе __missing__ используйте self[key], чтобы сохранить элемент на self для данного key и вернуть его:
class Mydict(dict):
def __missing__(self, key):
self[key] = new_item = [] # create and store a new list
return new_item # return the newly created list
Это гарантирует, что вы можете напрямую изменить вновь добавленный элемент:
>>> d = Mydict()
>>> d['x']
[]
>>> d['x'].extend([1,2,3,4,5])
>>> d
{'x': [1, 2, 3, 4, 5]}
self.keyопределенно не будет работать, потому что вы касаетесь атрибута экземпляра в прямом смысле с именемkey.