[python] How can I get the name of an object in Python?

As others have mentioned, this is a really tricky question. Solutions to this are not "one size fits all", not even remotely. The difficulty (or ease) is really going to depend on your situation.

I have come to this problem on several occasions, but most recently while creating a debugging function. I wanted the function to take some unknown objects as arguments and print their declared names and contents. Getting the contents is easy of course, but the declared name is another story.

What follows is some of what I have come up with.

Return function name

Determining the name of a function is really easy as it has the __name__ attribute containing the function's declared name.

name_of_function = lambda x : x.__name__

def name_of_function(arg):
    try:
        return arg.__name__
    except AttributeError:
        pass`

Just as an example, if you create the function def test_function(): pass, then copy_function = test_function, then name_of_function(copy_function), it will return test_function.

Return first matching object name

  1. Check whether the object has a __name__ attribute and return it if so (declared functions only). Note that you may remove this test as the name will still be in globals().

  2. Compare the value of arg with the values of items in globals() and return the name of the first match. Note that I am filtering out names starting with '_'.

The result will consist of the name of the first matching object otherwise None.

def name_of_object(arg):
    # check __name__ attribute (functions)
    try:
        return arg.__name__
    except AttributeError:
        pass

    for name, value in globals().items():
        if value is arg and not name.startswith('_'):
            return name

Return all matching object names

  • Compare the value of arg with the values of items in globals() and store names in a list. Note that I am filtering out names starting with '_'.

The result will consist of a list (for multiple matches), a string (for a single match), otherwise None. Of course you should adjust this behavior as needed.

def names_of_object(arg):
    results = [n for n, v in globals().items() if v is arg and not n.startswith('_')]
    return results[0] if len(results) is 1 else results if results else None