def getattr_by_path(obj, attr, *default):
    """Like getattr(), but can go down a hierarchy like 'attr.subattr'"""
    value = obj
    for part in attr.split('.'):
        if not hasattr(value, part) and len(default):
            return default[0]
        value = getattr(value, part)
        if callable(value):
            value = value()
    return value