Narażenie `defaultdict` jako zwykłego` dict`
ja używamdefaultdict(set)
wypełnić wewnętrzne mapowanie w bardzo dużej strukturze danych. Po wypełnieniu cała struktura (łącznie z mapowaniem) jest wystawiana na kod klienta. W tym momencie nie chcę, aby ktoś modyfikował mapowanie.
I nikt nie robi tego celowo. Ale czasami kod klienta może przez przypadek odnosić się do elementu, który nie istnieje. W tym momencie podniósłby się normalny słownikKeyError
, ale ponieważ mapowanie jestdefaultdict
, po prostu tworzy nowy element (pusty zestaw) w tym kluczu. Jest to dość trudne do złapania, ponieważ wszystko dzieje się cicho. Ale muszę się upewnić, że tak się nie stanie (semantyka właściwie się nie psuje, ale mapowanie rośnie do ogromnego rozmiaru).
Co powinienem zrobić? Widzę te wybory:
Znajdź wszystkie wystąpienia w bieżącym i przyszłym kodzie klienta, w których wykonywane jest wyszukiwanie słownika na mapowaniu i przekonwertuj je namapping.get(k, {})
zamiast. To jest po prostu okropne.
"Zamrażać"defaultdict
po całkowitym zainicjowaniu struktury danych przez jej konwersję nadict
. (Wiem, że tak naprawdę nie jest zamrożony, ale ufam, że kod klienta nie będzie faktycznie pisaćmapping[k] = v
.) Inelegant i duży hit wydajności.
Owinąćdefaultdict
w adict
berło. Co to jest elegancki sposób? Obawiam się, że uderzenie wydajności może być jednak ogromne (to wyszukiwanie jest mocno używane w wąskich pętlach).
Podklasadefaultdict
i dodaj metodę, która „zamyka” wszystkiedefaultdict
funkcje, dzięki czemu zachowuje się jak normalnydict
. Jest to wariant 3 powyżej, ale nie jestem pewien, czy jest szybszy. I nie wiem, czy jest to wykonalne bez polegania na szczegółach implementacji.
Używaj regularniedict
w strukturze danych, przepisując cały kod, aby najpierw sprawdzić, czy element znajduje się w słowniku i dodać go, jeśli nie jest. Niedobrze.