How to correctly implement the mapping protocol in Python?

I use python-spidermonkey, which internally uses PyMapping_Check to determine if the object used as global (in rt.new_context (global)) is mapped. (This is basically a dictionary passed in python-spidermonkey, so javascript has limited access to python variables.)

There is no official definition that I could find in the mapping protocol in Python, so I used a trial version and an error to determine what was in it. Have an official link?

+8
python
source share
1 answer

The collections.abc module defines interfaces for things like Mapping , Sequence , etc.

Inheriting from the abstract base classes in this module, you get standard implementations of some methods. Therefore, to be considered Mapping , your class definition should look something like this:

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

Inheriting from Mapping , you get "free" implementations of most of the useful dict methods:

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

If these default implementations are ineffective with your custom data structure, you can always override them with your versions.


To be considered MutableMapping , your class interface should look like this:

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

Inheriting from MutableMapping , you get "free" definitions of all Mapping methods, plus:

  • pop
  • popitem
  • clear
  • update
  • setdefault

If you are "folding your own" from scratch and do not want to use an abstract base class, you should probably try to define all the above methods if you want your class to be strictly Liskov-replaceable for dict .

+14
source share

All Articles