2010-08-02 24 views
8

Quiero implementar una clase que contendrá wrap - no subclase - el objeto python dict, de modo que cuando se detecte un cambio en un almacén de respaldo pueda volver a crear el objeto dict delegado. Tengo la intención de verificar los cambios en la tienda de respaldo cada vez que se accede al dict para leer.Cómo envolver un dict python?

Supongamos que debo crear un objeto para actuar así; ¿Qué métodos necesitaría implementar?

Respuesta

12

Puede subclase el ABC (clase base abstracta) collections.Mapping (o collections.MutableMapping si también quiere permitir que el código usando las instancias a alterar el diccionario simulada/envuelta, por ejemplo, mediante la asignación indexada, pop, etc).

Si es así, entonces, como los documentos que apuntaban a implicar un tanto indirectamente, los métodos que necesita para implementar son

__len__ 
__iter__ 
__getitem__ 

(para un Mapping) - que debe aplicar también

__contains__ 

porque al delegar en el dict que está envolviendo se puede hacer mucho más rápido que el enfoque iterativo que el ABC debería aplicar de lo contrario.

Si necesita suministrar una MutableMapping entonces también se deben aplicar métodos más 2:

__setitem__ 
__delitem__  
+0

¿Hay alguna manera, en python 3, de reenviar todos esos métodos "a granel", sin copiar/pegar manualmente el código casi idéntico para cada uno de ellos? El '__getattr__' normal no funciona, ya que se buscan métodos especiales en la clase en lugar de instancia, y esa búsqueda omite' __getattr__'. – max

1

creo que depende de los métodos que utiliza. Probablemente __getitem__, __setitem__, __iter__ y __len__ ya que la mayoría de las cosas se pueden implementar en términos de eso. Pero querrá ver algunos casos de uso, particularmente con __iter__. Algo como esto:

for key in wrapped_dictionary: 
    do_something(wrapped_dictionary[key]) 

... va a ser lento si se golpea la fuente de datos en cada iteración, por no hablar de que no podría trabajar incluso si la fuente de datos está cambiando por debajo suyo. Por lo tanto, querrá lanzar una especie de excepción e implementar iteritems como alternativa, cargando todos los pares clave-valor en un lote antes de recorrerlos.

Pythondocs tienen listas de productos donde puede buscar métodos y casos de uso.

2

Además de lo que ya se ha sugerido, es posible que desee echar un vistazo a UserDict.

Para ver un ejemplo de un objeto similar a dict, puede leer a través de django session implementation, específicamente la clase SessionBase.

+0

Según lo sugerido por el enlace de documentación proporcionado, UserDict ha sido suplantado por las subclases dict (desde Python 2.2) y el enfoque ABC sugerido por Alex Martelli (desde Python 2.6). – NeilenMarais

Cuestiones relacionadas