Skip to content

Instantly share code, notes, and snippets.

@JordanReiter
Created September 30, 2015 19:29
Show Gist options
  • Save JordanReiter/0ad11d6d1ab215b654c6 to your computer and use it in GitHub Desktop.
Save JordanReiter/0ad11d6d1ab215b654c6 to your computer and use it in GitHub Desktop.
Access values from an object using dot notation.
def get_dotted_value(obj, attr=None):
"""Access values from an object using dot notation.
Can be attributes, keys, or indices.
>>> class SampleObject():
... def __repr__(self):
... return repr(sorted(self.__dict__.items()))
...
>>> zoo = SampleObject()
>>> lion = SampleObject()
>>> lion.color = "Yellow"
>>> lion.foods = [ "zebras", "giraffes", "buffalo" ]
>>> bear = SampleObject()
>>> bear.color = "Brown"
>>> bear.foods = [ "insects", " honey " ]
>>> zebra = SampleObject()
>>> zebra.color = "Striped"
>>> zebra.foods = [ "grass", "hay" ]
>>> zoo.animals = { 'lion': lion, 'bear': bear, 'zebra': zebra }
>>> # simple attribute access
... sorted(get_dotted_value(zoo, "animals").items())
[('bear', [('color', 'Brown'), ('foods', ['insects', ' honey '])]), ('lion', [('color', 'Yellow'), ('foods', ['zebras', 'giraffes', 'buffalo'])]), ('zebra', [('color', 'Striped'), ('foods', ['grass', 'hay'])])]
>>> # attribute + dictionary
>>> get_dotted_value(zoo, "animals.lion")
[('color', 'Yellow'), ('foods', ['zebras', 'giraffes', 'buffalo'])]
>>> # attribute + dictionary + attribute
>>> get_dotted_value(zoo, "animals.lion.color")
'Yellow'
>>> # attribute + dictionary + attribute + list index
>>> get_dotted_value(zoo, "animals.lion.foods.2")
'buffalo'
>>> # attribute + dictionary + attribute + list index + callable attribue
>>> get_dotted_value(zoo, "animals.bear.foods.1.strip")
'honey'
>>>
"""
if not attr:
return obj
for current_attr in attr.split('.'):
try:
obj = obj[current_attr]
continue
except AttributeError:
pass
except TypeError as type_err:
if 'indices' in str(type_err):
try:
obj = obj[int(current_attr)]
continue
except ValueError as val_err:
if 'literal' not in str(val_err):
raise
obj = getattr(obj, current_attr)
if not obj:
return
if callable(obj):
return obj()
return obj
if __name__ == "__main__":
import doctest
doctest.testmod()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment