Reputation: 363586
The documentation lists 3 ways for creating a dict instance:
class dict(**kwarg)
class dict(mapping, **kwarg)
class dict(iterable, **kwarg)
What exactly is a mapping here? What's the minimal interface required for dict(mapping)
to work?
Upvotes: 22
Views: 20037
Reputation: 168876
From the source code for CPython, this comment:
/* We accept for the argument either a concrete dictionary object,
* or an abstract "mapping" object. For the former, we can do
* things quite efficiently. For the latter, we only require that
* PyMapping_Keys() and PyObject_GetItem() be supported.
*/
So, "the minimal interface required for dict(mapping) to work" appears to be .keys()
and .__getitem__()
.
Example program:
class M:
def keys(self):
return [1,2,3]
def __getitem__(self, x):
return x*2
m = M()
d = dict(m)
assert d == {1:2, 2:4, 3:6}
Upvotes: 21
Reputation: 363586
It seems that implementing only keys
and __getitem__
is sufficient.
>>> class mydict:
... def keys(self):
... return 'xyz'
... def __getitem__(self, item):
... return 'potato'
...
>>> dict(mydict())
{'x': 'potato', 'y': 'potato', 'z': 'potato'}
Upvotes: 4
Reputation: 36433
As usual, feel free to peruse the code :)
So, let's go into Include/dictobject.h
:
132 /* PyDict_Merge updates/merges from a mapping object (an object that
133 supports PyMapping_Keys() and PyObject_GetItem()). If override is true,
134 the last occurrence of a key wins, else the first. The Python
135 dict.update(other) is equivalent to PyDict_Merge(dict, other, 1).
136 */
So we're looking for things that have PyMapping_Keys
and PyObject_GetItem
. Because we're lazy, we just use the search box in the python docs and find the mappings protocol. So if your CPython PyObject follows that protocol, you're good to go.
Upvotes: 2
Reputation: 723
It's the best answer for your question:
https://docs.python.org/2/library/stdtypes.html#typesmapping
It's the simplest example of mapping: {}
If you want to create a custom mapping type, you may inherit it from base dict
and overwrite __getitem__
magic method(it depends on your needs)
Upvotes: -1
Reputation: 37364
The glossary defines it as:
A container object that supports arbitrary key lookups and implements the methods specified in the Mapping or MutableMapping abstract base classes. Examples include
dict
,collections.defaultdict
,collections.OrderedDict
andcollections.Counter
.
So it looks like the minimal list of methods to meet the definition is __getitem__
, __iter__
, __len__
, __contains__
, keys
, items
, values
, get
, __eq__
, and __ne__
. Although I bet the dict constructor does not actually need all of those.
Upvotes: 7