Я использую defaultdict(set)
для заполнения внутреннего сопоставления в очень большой структуре данных. После его заполнения вся структура (включая отображение) подвергается клиенту. В этот момент я не хочу, чтобы кто-либо модифицировал отображение.
И никто не делает это намеренно. Но иногда код клиента может случайно ссылаться на элемент, который не существует. В этот момент нормальный словарь поднял бы KeyError
, но так как отображение defaultdict
, оно просто создает новый элемент (пустой набор) в этом ключе. Это довольно сложно поймать, поскольку все происходит тихо. Но мне нужно, чтобы этого не произошло (семантика на самом деле не сломается, но отображение растет до огромного размера).
Что мне делать? Я вижу эти варианты:
-
Найти все экземпляры в текущем и будущем клиентском коде, где выполняется поиск словаря при сопоставлении, и преобразовать его в
mapping.get(k, {})
. Это просто ужасно. -
"Замораживание"
defaultdict
после полной инициализации структуры данных путем преобразования ее вdict
. (Я знаю, что это действительно не заморожено, но я доверяю клиентскому коду, чтобы на самом деле не писатьmapping[k] = v
.) Inelegant и большой успех. -
Оберните
defaultdict
в интерфейсdict
. Какой изящный способ сделать это? Я боюсь, что удар производительности может быть огромным (этот поиск сильно используется в жестких циклах). -
Подкласс
defaultdict
и добавьте метод, который "отключает" все функцииdefaultdict
, оставляя его так, как если бы он был обычнымdict
. Это вариант из 3 выше, но я не уверен, если он будет быстрее. И я не знаю, можно ли это сделать, не полагаясь на детали реализации. -
Используйте регулярную
dict
в структуре данных, переписывая весь код там, чтобы сначала проверить, находится ли элемент в словаре, и добавить его, если это не так. Нехорошо.