Return a (nested) attribute value.

The first attribute found is returned. Nested objects are traversed depth-first in post-order, with level-wise order determined by the list ordering returned from nested_lookup_fn.

obj The object to find (nested) attributes in.
attr A string attribute name to search for.
default If attr does not exist in obj or nested objects, and default is set, return default.
nested_lookup_fn A single-argument callable that returns a list of (attribute name, nested object) pairs. Defaults to get_nested_objs.

value The (nested) attribute value, or default if it does not exist and default is set.

AttributeError if attr is not found and default is not specified.