I needed to check if the object is one of the following types: dict, OrderedDict, defaultdict.
assert all([dictalike(x) for x in [dict(), OrderedDict(), defaultdict()]) assert not any([dictalike(x) for x in [str(), int(), float(), ...])
Several possibilities are functional:
Check for type
and type.__bases__
– cause OrderedDict
and defaultdict
both inherits from dict
. = Check if the object is an instance of given class or sublcass.
In [41]: import collections as c In [42]: [dict in [type(x)] + list(type(x).__bases__) for x in [dict(), c.OrderedDict(), c.defaultdict(), str()]] Out[42]: [True, True, True, False]
or simply check for __iter__ in dir(x)
In [41]: import collections as c In [42]: [hasattr(x, '__iter__') for x in [dict(), c.OrderedDict(), c.defaultdict(), str()]] Out[42]: [True, True, True, True]
or you can use the collections.Iterable
In [41]: import collections as c In [42]: [isinstance(x, c.Iterable) for x in [dict(), c.OrderedDict(), c.defaultdict(), str()]] Out[42]: [True, True, True, True]
thought, all three options will get true even for str
The best
The best option would therefore be to check if it’s type collections.Mapping
In [41]: import collections as c In [42]: [isinstance(x, c.Mapping) for x in [dict(), c.OrderedDict(), c.defaultdict(), str()]] Out[42]: [True, True, True, False]
The function would be:
from collections import Mapping def dictalike(obj): return isinstance(x, Mapping)
Though it would not check for object iterable via __getitem__
You can write more possible checks to the comments :).
[0] Based on stackoverflow q