Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to correctly implement the mapping protocol in Python?

Tags:

python

I'm using python-spidermonkey, which internally uses PyMapping_Check to identify if the object being used as a global (in rt.new_context(global)) implements the mapping protocol. (This is basically a dictionary passed to python-spidermonkey so that javascript has limited access to python variables.)

There's no official definition I could find of the mapping protocol in Python, so I've been using trial and error to determine what's in it. Is there an official reference?

like image 370
Chris Avatar asked Nov 04 '13 19:11

Chris


People also ask

What is mapping type in Python?

A mapping type is a data type comprised of a collection of keys and associated values. Python's only built-in mapping type is the dictionary. Dictionaries implement the associative array abstract data type.

What is mapping object in Python?

A mapping object maps values of one type (the key type) to arbitrary objects. Mappings are mutable objects. There is currently only one mapping type, the dictionary . A dictionary's keys are almost arbitrary values.

What is map in Python with example?

Python map() function with EXAMPLES. Steve Campbell September 10, 2022. Python map() applies a function on all the items of an iterator given as input. An iterator, for example, can be a list, a tuple, a set, a dictionary, a string, and it returns an iterable map object. Python map() is a built-in function.

What are Python protocols?

What is the python Protocol class? Protocol class was added to Python 3.8 as part of PEP 544 as a mechanism for “structural subtyping.” Basically, it is used to define an interface class that acts as a blueprint for designing other classes.


1 Answers

The collections.abc module defines the interfaces for things like Mapping, Sequence, and so on.

By inheriting from the abstract base classes in that module, you get default implementations of some of the methods. So to be considered a Mapping, your class definition should look something like this:

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

Inheriting from Mapping will get you 'free' implementations of most of dict's useful methods:

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

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


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

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

Inheriting from MutableMapping gets you 'free' definitions of all of Mapping's methods, plus:

  • pop
  • popitem
  • clear
  • update
  • setdefault

If you're 'rolling your own' from scratch and don't want to use an abstract base class, you should probably try to define all of the above methods, if you want your class to be strictly Liskov-substitutable for dict.

like image 94
Benjamin Hodgson Avatar answered Oct 05 '22 10:10

Benjamin Hodgson