Я хочу реализовать подобную диктату структуру данных, которая имеет следующие свойства:
from collections import UserDict
class TestDict(UserDict):
pass
test_dict = TestDict()
# Create empty dictionaries at 'level_1' and 'level_2' and insert 'Hello' at the 'level_3' key.
test_dict['level_1']['level_2']['level_3'] = 'Hello'
>>> test_dict
{
'level_1': {
'level_2': {
'level_3': 'Hello'
}
}
}
# However, this should not return an empty dictionary but raise a KeyError.
>>> test_dict['unknown_key']
KeyError: 'unknown_key'
Проблема, насколько мне известно, заключается в том, что python не знает, вызывается ли __getitem__
в контексте установки элемента, то есть в первом примере, или в контексте получения и элемента, во втором примере.
Я уже видел Python `defaultdict`: использовать значение по умолчанию при настройке , но не при получении , но я не думаю, что этот вопрос является дубликатом или что он отвечает на мой вопрос.
Пожалуйста, дайте мне знать, если у вас есть какие-либо идеи.
Заранее спасибо.
РЕДАКТИРОВАТЬ:
Можно добиться чего-то похожего, используя:
def set_nested_item(dict_in: Union[dict, TestDict], value, keys):
for i, key in enumerate(keys):
is_last = i == (len(keys) - 1)
if is_last:
dict_in[key] = value
else:
if key not in dict_in:
dict_in[key] = {}
else:
if not isinstance(dict_in[key], (dict, TestDict)):
dict_in[key] = {}
dict_in[key] = set_nested_item(dict_in[key], value, keys[(i + 1):])
return dict_in
class TestDict(UserDict):
def __init__(self):
super().__init__()
def __setitem__(self, key, value):
if isinstance(key, list):
self.update(set_nested_item(self, value, key))
else:
super().__setitem__(key, value)
test_dict[['level_1', 'level_2', 'level_3']] = 'Hello'
>>> test_dict
{
'level_1': {
'level_2': {
'level_3': 'Hello'
}
}
}