Expondo o `defaultdict` como um` dict` regular
estou usandodefaultdict(set)
para preencher um mapeamento interno em uma estrutura de dados muito grande. Depois de preenchido, toda a estrutura (incluindo o mapeamento) é exposta ao código do cliente. Nesse ponto, não quero que ninguém modifique o mapeamento.
E ninguém faz, intencionalmente. Mas, às vezes, o código do cliente pode se referir acidentalmente a um elemento que não existe. Nesse ponto, um dicionário normal teria levantadoKeyError
, mas como o mapeamento édefaultdict
simplesmente cria um novo elemento (um conjunto vazio) nessa chave. Isso é muito difícil de pegar, já que tudo acontece em silêncio. Mas eu preciso garantir que isso não aconteça (a semântica realmente não quebra, mas o mapeamento cresce para um tamanho enorme).
O que devo fazer? Eu posso ver estas escolhas:
Encontre todas as instâncias no código do cliente atual e futuro em que uma consulta de dicionário é executada no mapeamento e converta-a emmapping.get(k, {})
em vez de. Isso é simplesmente terrível.
"Congelar"defaultdict
após a estrutura de dados ser totalmente inicializada, convertendo-a paradict
. (Eu sei que não é realmente congelado, mas eu confio no código do cliente para não realmente escrevermapping[k] = v
.) Inelegant, e um grande sucesso de performance.
Embrulhodefaultdict
dentro dedict
interface. O que é uma maneira elegante de fazer isso? Eu tenho medo que o acerto de performance possa ser enorme (essa pesquisa é muito usada em loops apertados).
Subclassedefaultdict
e adicione um método que "encerre" todos osdefaultdict
características, deixando-o para se comportar como se fosse umdict
. É uma variante de 3 acima, mas não tenho certeza se é mais rápido. E eu não sei se é factível sem depender dos detalhes da implementação.
Use regulardict
na estrutura de dados, reescrevendo todo o código para primeiro verificar se o elemento está no dicionário e adicioná-lo se não estiver. Não é bom.