Exponer `defaultdict` como un` dict` regular
estoy usandodefaultdict(set)
para rellenar una asignación interna en una estructura de datos muy grande. Una vez rellenado, toda la estructura (incluida la asignación) se expone al código del cliente. En ese momento, no quiero que nadie modifique el mapeo.
Y nadie lo hace, intencionalmente. Pero a veces, el código del cliente puede referirse accidentalmente a un elemento que no existe. En ese punto, un diccionario normal habría subidoKeyError
, pero ya que el mapeo esdefaultdict
, simplemente crea un nuevo elemento (un conjunto vacío) en esa clave. Esto es bastante difícil de atrapar, ya que todo sucede en silencio. Pero necesito asegurarme de que esto no suceda (la semántica en realidad no se rompe, pero el mapeo crece a un tamaño enorme).
¿Qué tengo que hacer? Puedo ver estas opciones:
Encuentre todas las instancias en el código de cliente actual y futuro donde se realiza una búsqueda de diccionario en el mapeo, y conviértalo amapping.get(k, {})
en lugar. Esto es simplemente terrible.
"Congelar"defaultdict
después de que la estructura de datos esté completamente inicializada, al convertirla adict
. (Sé que no está realmente congelado, pero confío en que el código del cliente no escriba realmentemapping[k] = v
.) Inelegante, y un gran éxito de rendimiento.
Envolverdefaultdict
en unadict
interfaz. ¿Qué es una manera elegante de hacer eso? Sin embargo, me temo que el impacto en el rendimiento puede ser enorme (esta búsqueda es muy utilizada en bucles ajustados).
Subclasedefaultdict
y agrega un método que "apaga" todas lasdefaultdict
características, dejando que se comporte como si fuera un regulardict
. Es una variante de 3 arriba, pero no estoy seguro si es más rápido. Y no sé si es factible sin confiar en los detalles de la implementación.
Usar regulardict
en la estructura de datos, reescriba todo el código para verificar primero si el elemento está en el diccionario y agregarlo si no lo está. No está bien.