superclasses herency classes animal python subclass

python - herency - Dict de subclase: ¿UserDict, dict o ABC?



python superclasses (3)

Basado en el libro Secrets Recipes of the Python Ninja

Lo único especial que el UserDict tiene más allá de las operaciones normales del diccionario es un único atributo:

datos: un diccionario real para contener los contenidos de la clase UserDict

Para acceder a los elementos en el diccionario, debe iterar sobre ellos o llamar a elementos (). Si bien la instancia de UserDict admite los mismos métodos, la vista devuelta por los elementos () es notablemente diferente:

>>> from collections import UserDict >>> a = UserDict(a=1) >>> d = dict(d=3) # regular dictionary for comparison >>> for k in d: ... print(k, d[k]) ... d 3 >>> d.items() dict_items([(''d'', 3)]) >>> for k in a: ... print(k, a[k]) ... a 1 >>> a.items() ItemsView({''a'': 1})

Observe que el objeto de diccionario devuelve una tupla de clave / valores. El UserDict devuelve un objeto de diccionario real. Dependiendo de lo que esté haciendo, esta diferencia puede ser importante, como lo es la capacidad de usar el atributo de datos para acceder al diccionario.

¿Cuál es la diferencia entre UserDict , dict y ABC y cuál se recomienda? ¿Los documentos parecen despreciar UserDict ?

También parece que la update() de UserDict update() usaría mi método setitem mientras que dict no? ¿Qué métodos son realmente esenciales para anular dado que quiero la función personalizada setitem y getitem ?

Con ABC s, tendría que implementar absolutamente todos los métodos, ya que no proporciona una implementación predeterminada.

Quiero hacer un dict que haga dos cosas:

  • intern() todas las claves y valores
  • almacenar algunos de los valores en una base de datos SQLite

Entonces, ¿qué tipo de UserDict , dict y ABC me permitirán hacer esto?


No use la clase UserDict , no la necesita. Como dicen los documentos, puedes simplemente subclasificar dict directamente.

Sin embargo, aún desea el módulo DictMixin para DictMixin :

Nota: DictMixin , aunque no se ha desaprobado oficialmente, se ha eliminado en Python 3, y se recomienda en los documentos que use collections.MutableMapping . Sin embargo, esto tiene un inconveniente: debe implementar más de la interfaz del diccionario: __delitem__ , __getitem__ , __iter__ , __len__ , y __setitem__ . Con DictMixin , puede implementar los que desea cambiar, y el resto usar una implementación predeterminada.

from UserDict import DictMixin class MyDict(DictMixin, dict): def __setitem__(self, key, value): print key, value # just an example # use intern(key) or whatever here dict.__setitem__(self, key, value) # or # super(MyDict, self).__setitem__(key, value) m = MyDict() m[''a''] = ''b'' # a b m.update({''a'': ''c''}) # a c

Automáticamente hará que la update use tu __setitem__ como quieras.


Si desea una colección personalizada que en realidad contenga los datos, subclase dict . Esto es especialmente útil si desea extender la interfaz (por ejemplo, agregar métodos).

Ninguno de los métodos incorporados llamará a su __getitem__ / __setitem__ , sin embargo. Si necesita un control total sobre estos, cree una clase personalizada que implemente la clase base abstracta collections.MutableMapping lugar.

El ABC no proporciona un medio para almacenar los datos reales, solo una interfaz con implementaciones predeterminadas para algunos métodos. Sin embargo, estas implementaciones predeterminadas llamarán a su __getitem__ y __setitem__ . Deberá usar un dict interno para contener los datos e implementar todos los métodos abstractos: __len__ , __iter__ , __getitem__ , __setitem__ y __delitem__ .

La clase UserDict del módulo de collections (en Python 2, el módulo también se llama UserDict ) es un contenedor alrededor de un dict interno, implementando el MutableMapping ABC. Si desea personalizar el comportamiento de un dict , esta implementación podría ser un punto de partida.

En resumen:

  • MutableMapping define la interfaz. Subclase esto para crear algo que actúe como un dict . Depende totalmente de ti si y cómo almacenas los datos.
  • UserDict es una implementación de MutableMapping usa un dict interno "real" como almacenamiento. Si desea una colección de almacenamiento tipo dict pero anula algunos métodos expuestos por dict , este podría ser un buen punto de partida para usted. Pero asegúrese de leer el código para saber cómo se implementan los métodos básicos, para que sea coherente al anular un método.
  • dict es "lo real". Subclase esto si desea extender la interfaz. Anular los métodos para hacer cosas personalizadas puede ser peligroso, ya que generalmente hay varias formas de acceder a los datos, y podrías terminar con una API inconsistente.