Aquí está una doble pregunta, con una parte teórica y una práctica:Subclassing dict: se debe llamar a dict .__ init __()?
Cuando la subclasificación dict:
class ImageDB(dict):
def __init__(self, directory):
dict.__init__(self) # Necessary??
...
debe dict.__init__(self)
ser llamado, simplemente como una medida de "seguridad" (por ejemplo, en el caso hay algunos detalles de implementación no triviales que importan) ¿Existe un riesgo de que el código se rompa con una versión futura de Python si se llama dict.__init__()
no? Estoy buscando una razón fundamental para hacer una cosa o la otra, aquí (prácticamente, llamar al dict.__init__()
es seguro).
Supongo que cuando se llama ImageDB.__init__(self, directory)
, el yo ya es un nuevo objeto dict vacío, y que, por lo tanto, no es necesario llamar al dict.__init__
(al principio quiero que el dict esté vacío). ¿Es esto correcto?
Editar:
La pregunta más práctica detrás de la pregunta fundamental anterior es la siguiente. Estaba pensando en subclasificar dict porque usaría la sintaxis [...] db con bastante frecuencia (en lugar de hacer db.contents [...] todo el tiempo); el único dato (atributo) del objeto es realmente un dict. Deseo agregar algunos métodos a la base de datos (como get_image_by_name()
, o get_image_by_code()
, por ejemplo), y solo anular __init__()
, porque la base de datos de imágenes está definida por el directorio que la contiene.
En resumen, la pregunta (práctica) podría ser: ¿qué es una buena implementación para algo que se comporta como un diccionario, excepto que su inicialización es diferente (solo toma el nombre de un directorio) y tiene métodos?
"Fábricas" se mencionaron en muchas respuestas. Así que supongo que todo se reduce a: ¿subclasifica dict, anula __init__()
y agrega métodos, o escribe una función (de fábrica) que devuelve un dict, al que agrega métodos? Me inclino a preferir la primera solución, porque la función de fábrica devuelve un objeto cuyo tipo no indica que tenga semántica y métodos adicionales, pero ¿qué piensas?
Editar 2:
que deduzco de la respuesta de todo el mundo que no es una buena idea a la subclase dict cuando la nueva clase "no es un diccionario", y en particular cuando su método __init__
no puede tener el mismo argumentos como dict's __init__
(que es el caso en la "pregunta práctica" anterior). En otras palabras, si entiendo correctamente, el consenso parece ser: cuando subclases, todos los métodos (incluida la inicialización) deben tener la misma firma que los métodos de la clase base. Esto permite que isinstance (subclass_instance, dict) garantice que subclass_instance.__init__()
se pueda usar como dict.__init__()
, por ejemplo.
Luego aparece otra pregunta práctica: ¿cómo debe implementarse una clase que sea como dict, excepto por su método de inicialización? sin subclases? esto requeriría un código repetitivo molesto, ¿no?
Una función de fábrica es el camino a seguir. Si necesita personalizar el comportamiento * instancia *, entonces puede querer crear una subclase. Si solo desea anular la * inicialización *, no necesita crear subclases, ya que sus instancias no son diferentes de las estándar. Recuerde que __init__ no se considera parte de la interfaz de la instancia, sino de la clase. –
Por lo que veo para este problema, sería mejor agregar el método '__getitem__' a su ImageDB en lugar de subclasificar un dict, porque no es un dict. Esto le permite hacer lo que quiera, _sin_ tener todos los métodos como 'pop()' que parecen ser inapropiados para su clase. –
@gs: Buen punto, sobre pop; es, de hecho, al menos por el momento, irrelevante (el contenido de la base de datos se define solo en la inicialización). Creo que de hecho es mejor que la implementación se ajuste perfectamente a las características necesarias. – EOL