I need to test if objects read in from a file (and eval
ed) with ConfigParser
are mappings.
Not entirely sure about the terminology here, but let me explain. Given that my object is called O
it must support being used in the following manner:
def tester(**kwargs):
print kwargs
tester(**O)
If O
was not supporting the ** this would result in a TypeError, e.g. TypeError: test() argument after ** must be a mapping, not tuple
.
It's a really simple scenario, but I need to know that O
will work before using it and I need to be absolutely certain it won't fail. If I was testing O
for being an iterable, I would use something like:
try:
iter(O)
except:
O = tuple()
As discussed in In Python, how do I determine if an object is iterable?
I can't find any parallel for mappings. As discussed in the same answer above, using isinstance
and collections
isn't an good solution.
So do I have to make my tester-function above (without the print) as my own mapping-test when loading the objects like
try:
tester(**O)
except TypeError:
O = {}
or does python have a built in way to test this like there is for iterables? It seems there should be one.
Edit
Actually the linked answer above never spoke against the isinstance method, should have read it better...
Use the collections.abc.Mapping
ABC:
from collections.abc import Mapping
if isinstance(O, Mapping):
# O is a mapping
This supports any object that implements the right methods to be considered a mapping, including dict
.
Demo:
>>> from collections.abc import Mapping
>>> isinstance({}, Mapping)
True
>>> isinstance((), Mapping)
False
Some objects may not be instances of collections.Mapping
and yet can be unpacked using double-star syntax(**
):
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
The minimal interface that obj
must supply is keys
and __getitem__
:
print(all(hasattr(obj, attr) for attr in ('keys', '__getitem__')))
# True
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With