def nameof(obj):
    """Give the name of an object.

    First try normally named object (those having a ``'__name__'`` attribute);
    then some special classes instances that wraps the name internally are
    checked; then it tests for some objects that are singletons [#sing]_;
    finally -as a default tentative- return the type name.

    For example::

      >>> nameof(object)
      'object'

      >>> nameof(lambda x: x)
      '<lambda>'

      >>> singletons = (None, True, False, Ellipsis, NotImplemented)
      >>> [nameof(s) for s in singletons]
      ['None', 'True', 'False', 'Ellipsis', 'NotImplemented']

      >>> nameof(0)
      'int'

    This is a beginning intended to deprecate a "fauna" of several existing
    functions with the same purpose around several modules.

    .. [#sing] In this case an object is considered a signgleton if both of
               its representation strings (``str(obj)`` and ``repr(obj)``)
               match and it is a valid identifier.

    """
    try:
        return obj.__name__
    except AttributeError:
        if isinstance(obj, (staticmethod, classmethod)):
            return obj.__func__.__name__
        else:
            import re
            res = str(obj)
            identifier_regex = '(?i)^[_a-z][_a-z0-9]*$'
            if res == repr(obj) and re.match(identifier_regex, res):
                return res
            else:
                return type(obj).__name__
