Gets the #str name of @obj

        @obj: any python object
        @full: #bool returns with parent name as well if True

        -> #str object name
        ..
            from redis_structures.debug import get_parent_obj

            get_obj_name(get_obj_name)
            # -> 'get_obj_name'

            get_obj_name(redis_structures.debug.Timer)
            # -> 'Timer'
        ..

def get_obj_name(obj, full=True):
    """ Gets the #str name of @obj

        @obj: any python object
        @full: #bool returns with parent name as well if True

        -> #str object name
        ..
            from redis_structures.debug import get_parent_obj

            get_obj_name(get_obj_name)
            # -> 'get_obj_name'

            get_obj_name(redis_structures.debug.Timer)
            # -> 'Timer'
        ..
    """
    has_name_attr = hasattr(obj, '__name__')
    if has_name_attr and obj.__name__ == "<lambda>":
        try:
            src = whitespace_sub("", inspect.getsource(obj))\
                .replace("\n", "; ").strip(" <>")
        except OSError:
            src = obj.__name__
        return lambda_sub("", src)
    if hasattr(obj, '__qualname__') and obj.__qualname__:
        return obj.__qualname__.split(".")[-1]
    elif has_name_attr and obj.__name__:
        return obj.__name__.split(".")[-1]
    elif hasattr(obj, '__class__'):
        return str(obj.__class__.__name__).strip("<>")
    else:
        return str(obj.__repr__())