Если я понимаю, что вам нужно, мы действительно можем создать объект dict, который будет проверять тип для вас! Нет необходимости импорта.
Нам просто нужно создать подкласс для класса dict и переопределить функции для добавления элементов в словарь, чтобы мы могли проверять тип, прежде чем разрешать какие-либо добавления.
Вот код ниже.
class ClusterDict(dict):
key_type = str # we want all of our keys to be str type
value_type = list # same for our value as a list
# lets override the function for dictionary assignment so we can type check before we add to our dictionary
def __setitem__(self, key, value):
self.type_check_and_add(key, value)
# Lets override update as well
def update(self, **kwargs) -> None:
for key, value in kwargs.items():
self.type_check_and_add(key, value)
def type_check_and_add(self, key: str, value: list) -> None:
assert type(key) == self.key_type, f"Expected {self.key_type} for key, got {type(key)} instead."
if type(value) is not list:
value = [value] # Make it a list if its isn't, remove this if you know it will always come as a list, even if its a single entry, like [5], or [(2, 6)]
assert type(value) == self.value_type, f"Expected {self.value_type} for key, got {type(value)} instead."
val_type = type(value[0]) # type of first item in list, lets make sure they all match this one
for val in value:
assert type(val) == val_type, f"Items do not have matching types for key {key}."
super().__setitem__(key, value) # this then passes assignment as usual to the base class dict
Пройдем несколько тестов сейчас!
if __name__ == '__main__':
clust = ClusterDict()
input_data = {
'Height': [4, 3, 5],
'Age': [(4, 9), (4, 6, 8)]
}
clust.update(**input_data)
print(clust)
{'Height': [4, 3, 5], 'Age': [(4, 9), (4, 6, 8)]}
Пока все выглядит хорошо, мы можем добавлять целые словари, используя обновление как обычно
input_data = {'Weights': [1, 34, 3, 90]}
clust.update(**input_data)
print(clust)
{'Height': [4, 3, 5], 'Age': [(4, 9), (4, 6, 8)], 'Weights': [1, 34, 3, 90]}
Или только одна запись за раз.
Давайте попробуем обычным способом, dict [ключ] = значение
clust['Hobbies'] = [(3, 's', {'name': 'Sam'}), (4, 5), (), (True,)]
print(clust)
{'Height': [4, 3, 5], 'Age': [(4, 9), (4, 6, 8)], 'Weights': [1, 34, 3, 90], 'Hobbies': [(3, 's', {'name': 'Sam'}), (4, 5), (), (True,)]}
Хорошо выглядит. Но теперь давайте попробуем добавить список с типами, которые не соответствуют.
clust['My Favorite Number'] = [7, '7', (1, 1, 1, 1, 1, 1, 1)]
print(clust)
assert type(val) == val_type, f"Items do not have matching types for key {key}."
AssertionError: Items do not have matching types for key My Favorite Number.
, который выдает ошибку AssertionError и не позволяет нам делать это, как мы хотели.
Хотя бонус Поскольку мы подклассифицируем dict, мы получаем все его методы бесплатно!
>>>len(clust)
4
for k, v in clust.items():
... print(k, v)
...
Height [4, 3, 5]
Age [(4, 9), (4, 6, 8)]
Weights [1, 34, 3, 90]
Hobbies [(3, 's', {'name': 'Sam'}), (4, 5), (), (True,)]
Надеюсь, это то, что вы искали, и это поможет!