How to check if an object is a mapping (supports using ** O)

I need to check if the objects read from the file (and evaled) using ConfigParser, are mappings.

Not quite sure of the terminology, but let me explain. Given that my object is called O, it should support use as follows:

def tester(**kwargs):
     print kwargs

tester(**O)

If Onot supported **, this would lead to a TypeError, for example. TypeError: test() argument after ** must be a mapping, not tuple.

This is a very simple scenario, but I need to know what Owill work before using it, and I must be absolutely sure that it will not fail. If I were testing Oin order to be iterable, I would use something like:

try:
   iter(O)
except:
   O = tuple()

Python, , ?

. , isinstance collections .

- ( )

try:
    tester(**O)
except TypeError:
    O = {}

python , iterables? , .

Edit

, isinstance, ...

+4
2

collections.Mapping ABC:

from collections import Mapping

if isinstance(O, Mapping):
    # O is a mapping

, , , dict.

:

>>> from collections import Mapping
>>> isinstance({}, Mapping)
True
>>> isinstance((), Mapping)
False
+6

collections.Mapping (**):

import collections
def tester(**kwargs):
     print kwargs

class D:
    "http://stackoverflow.com/a/8601389/190597 (Raymond Hettinger)"
    def keys(self):
        return ['a', 'b']
    def __getitem__(self, key):
        return key.upper()

obj = D()
tester(**obj)
# {'a': 'A', 'b': 'B'}

print(isinstance(obj, collections.Mapping))
# False

, obj keys __getitem__:

print(all(hasattr(obj, attr) for attr in ('keys', '__getitem__')))
# True
+2

Source: https://habr.com/ru/post/1527725/


All Articles