Por ejemplo, supongamos que quiero subclase dicty tener todas las claves en mayúscula:
class capdict(dict):
def __init__(self,*args,**kwds):
super().__init__(*args,**kwds)
mod = [(k.capitalize(),v) for k,v in super().items()]
super().clear()
super().update(mod)
def __getitem__(self,key):
return super().__getitem__(key.capitalize())
def __setitem__(self,key,value):
super().__setitem__(key.capitalize(),value)
def __delitem__(self,key):
super().__detitem__(key.capitalize())
Esto funciona hasta cierto punto,
>>> ex = capdict(map(reversed,enumerate("abc")))
>>> ex
{'A': 0, 'B': 1, 'C': 2}
>>> ex['a']
0
pero, por supuesto, solo para los métodos que recordé implementar, por ejemplo
>>> 'a' in ex
False
No es el comportamiento deseado.
Ahora, la forma perezosa de completar todos los métodos que se pueden derivar de los "básicos" se estaría mezclando collections.abc.MutableMapping. Solo que no funciona aquí. Supongo que los métodos en cuestión ( __contains__en el ejemplo) ya los proporciona dict.
¿Hay alguna manera de tener mi pastel y comerlo? ¿Alguna magia para dejar MutableMappingver solo los métodos que he anulado para que reimplemente los otros basados en esos?
python
python-3.x
Paul Panzer
fuente
fuente

MutableMapping. Ver Diccionario insensible a mayúsculas y minúsculas .os._Environ.Respuestas:
Lo que puedes hacer:
Esto probablemente no funcionará bien (es decir, no es el diseño más limpio), pero podría heredar de MutableMapping primero y luego de dict segundo.
Entonces MutableMapping usaría cualquier método que haya implementado (porque son los primeros en la cadena de búsqueda):
Mejor manera:
El enfoque más limpio (fácil de entender y probar) es simplemente heredar de MutableMapping y luego implementar los métodos requeridos usando un dict regular como el almacén de datos base (con composición en lugar de herencia):
fuente
superexplícitosdict, parece funcionar, excepto laslendevoluciones0. ¿De dónde viene eso?(D, MutableMapping, dict). Ese es el método MutableMappiing .__ len __ () que siempre devuelve 0. No se debe llamar directamente; siempre se supone que debe anularse. Por eso tienes que llamardict.__len__(self)directamente. Y esa es una de las razones por las que dije "esto probablemente no funcionará bien" ;-)