Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

What is a mapping? PREMIUM

Trey Hunner smiling in a t-shirt against a yellow wall
Trey Hunner
3 min. read Watch as video Python 3.9—3.13

What is a mapping in Python?

Dictionary-like objects

Here we have an INI file, called pytest.ini:

[pytest]
norecursedirs = node_modules
addopts = --ignore=src
log_cli = True

We can parse this INI file using the ConfigParser class from Python's configparser module:

>>> from configparser import ConfigParser
>>> config = ConfigParser()
>>> config.read('pytest.ini')
['pytest.ini']

ConfigParser objects act like dictionaries. They aren't dictionaries, but they act like a dictionary.

Just like a dictionary, we can use square brackets ([...]) with a ConfigParser object.

>>> section = config['pytest']

The "keys" in a ConfigParser object are section names. Looking up a section by its name gives us back a Section object:

>>> section
<Section: pytest>

This Section object also acts like a dictionary. We can use square brackets with a Section: if we give it a key we'll get back the value for that key within our section:

>>> section['log_cli']
'True'

We can also use the built-in len function to get the number of key-value pairs within a section (just like a dictionary):

>>> len(section)
3

We can even use methods that you'd expect to find in a dictionary, like the keys method, the values method, and the items method:

>>> for name, value in section.items():
...     print(f"{name} = {value}")
...
norecursedirs = node_modules
addopts = --ignore=src
log_cli = True

In Python, we use the term mapping to refer to objects that act like a dictionary.

Our ConfigParser object and each Section object within it are mappings.

Mutable mappings

These ConfigParser and Section objects aren't just mappings, they're mutable mappings, meaning just like the built-in dict type, we can change their contents.

We could add a new key-value pair to a section:

>>> section['log_cli_level'] = 'INFO'

Or we could update the value for an existing key:

>>> section['log_cli'] = 'False'

We could also delete items from a section:

>>> del section['log_cli_level']

These objects are mutable, just as dictionaries in Python are mutable.

Immutable mappings

Not all mappings are mutable. One example of an immutable mapping is types.MappingProxyType.

>>> from types import MappingProxyType

The MappingProxyType class creates objects that wrap around an existing mapping and proxy operations to them. For example we could make a MappingProxyType object that wraps around our Section object:

>>> proxy = MappingProxyType(section)
>>> proxy
mappingproxy(<Section: pytest>)

This proxy object will proxy operations to our section mapping. So when we look up a key within it, it'll do the same thing as if we look up the key in our Section object:

>>> proxy['log_cli']
'False'

This proxy object is an immutable mapping object.

So while we can perform dictionary-like operations that don't mutate it, we can't perform any operations that would mutate it.

We could use its values method, for example:

>>> for value in proxy.values():
...     print(value)
...
node_modules
--ignore=src
False
INFO

Or we could use the built-in len function on it:

>>> len(proxy)
4

Or we could call its get method:

>>> proxy.get("pytest_classes", "Test*")
'Test*'

But we can't assign to its keys:

>>> proxy['log_cli'] = 'True'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item assignment

And we also can't delete key-value pairs from it:

>>> del proxy['log_cli']
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'mappingproxy' object does not support item deletion

Dictionaries are mutable mappings, but the word mapping doesn't imply mutability.

This object can't be mutated, but it is still a mapping. It's just an immutable mapping.

Think in mappings, not dictionaries

Mappings are used throughout the Python Standard Library and third-party libraries.

Mapping is just a generic word for a dictionary-like object. If an object can be subscripted (with square brackets) it's probably a mapping.

Mappings are typically expected to have a length, a get method, a values method, an items method, and a keys method, just like a dictionary would.

If an object can be mutated (just like dictionaries can) then it's a mutable mapping.

This is a free preview of a premium screencast. You have 2 previews remaining.