import inspect


def getmembers(obj, *predicates):
    """ Return all the members of an object as a list of `(key, value)` tuples, sorted by name.

    The optional list of predicates can be used to filter the members.

    The default predicate drops members whose name starts with '_'. To disable it, pass `None` as the first predicate.

    :param obj: Object to list the members for
    :param predicates: Functions to filter the members.

        If the first value is not None, a default predicate is added that filters private members out (name starts with '_')

    :type predicates: tuple[Callable|None]
    :returns: Sorted list of (name, value) tuples
    :rtype: list[(str, *)]
    """
    # Add default
    if not predicates or predicates[0] is not None:
        predicates = (lambda key, value: not key.startswith('_'),) + predicates
    # Build composite predicate
    def predicate(key_value_tuple):
        key, value = key_value_tuple
        for p in predicates:
            if p is not None and not p(key, value):
                return False
        return True
    # Filter
    return filter(predicate, inspect.getmembers(obj))