¿Cómo implementar correctamente el protocolo de mapeo en Python?

Estoy usando python-spidermonkey, que usa PyMapping_Check internamente para identificar si el objeto que se usa como global (en rt.new_context (global)) implementa el protocolo de mapeo. (Esto es básicamente un diccionario pasado a python-spidermonkey para que javascript tenga acceso limitado a las variables de python).

No hay una definición oficial que pueda encontrar del protocolo de mapeo en Python, así que he estado usando prueba y error para determinar qué contiene. ¿Hay alguna referencia oficial?

El módulo collections.abc define las interfaces para elementos como Mapping , Sequence , etc.

Al heredar de las clases base abstractas en ese módulo, obtiene implementaciones predeterminadas de algunos de los métodos. Por lo tanto, para ser considerado un Mapping , la definición de su clase debería verse así:

 class MyMapping(collections.abc.Mapping): def __getitem__(self, item) def __iter__(self) def __len__(self) 

La herencia de Mapping le dará implementaciones ‘gratuitas’ de la mayoría de los métodos útiles de dict :

  • __contains__
  • keys
  • items
  • values
  • get
  • __eq__
  • __ne__

Si estas implementaciones de métodos predeterminados son ineficientes con su estructura de datos personalizada, siempre puede anularlas con sus propias versiones.


Para ser considerado un MutableMapping , la interfaz de su clase debe tener este aspecto:

 class MyMutableMapping(collections.abc.MutableMapping): def __getitem__(self, item) def __setitem__(self, item) def __delitem__(self, item) def __iter__(self) def __len__(self) 

La herencia de MutableMapping le proporciona definiciones “libres” de todos los métodos de Mapping , además de:

  • pop
  • popitem
  • clear
  • update
  • setdefault

Si está ‘lanzando su propio’ desde cero y no quiere usar una clase base abstracta, probablemente debería tratar de definir todos los métodos anteriores, si desea que su clase sea estrictamente Liskov-sustituible por dict .