How to Get Name of a Function in Python
In Python, functions are "first-class objects." This means they can be assigned to variables, passed as arguments to other functions, and have attributes, just like any other object. One of the most useful attributes of a function object is __name__, which holds the function's name as a string.
This guide will show you how to access this attribute and demonstrate its practical applications in areas like debugging, logging, and metaprogramming with decorators.
Understanding the __name__ Attribute
Every function in Python has a set of special, built-in attributes that are denoted by double underscores (also known as "dunder" attributes). The __name__ attribute is one of these, and it simply returns a string containing the name used to define the function.
Getting the Name of a Simple Function
You can access the __name__ attribute directly from the function object or from any variable that references it.
Solution:
def my_custom_function():
"""A simple example function."""
print("Function is running!")
# Accessing the attribute directly from the function object
print(f"The function's name is: {my_custom_function.__name__}")
# Assigning the function to another variable
another_variable = my_custom_function
print(f"The name from the new variable is: {another_variable.__name__}")
Output:
The function's name is: my_custom_function
The name from the new variable is: my_custom_function
Practical Use Case: Logging in Decorators
A very common use for __name__ is inside decorators, where you might want to log which function is being called.
Solution:
import functools
def logging_decorator(func):
"""A simple decorator that logs when a function is called."""
@functools.wraps(func)
def wrapper(*args, **kwargs):
# Access the name of the function being wrapped
print(f"--- Calling function: '{func.__name__}' ---")
result = func(*args, **kwargs)
print(f"--- Finished function: '{func.__name__}' ---")
return result
return wrapper
@logging_decorator
def greet(name):
print(f"Hello, {name}!")
# Call the decorated function
greet("Alice")
Output:
--- Calling function: 'greet' ---
Hello, Alice!
--- Finished function: 'greet' ---
We use @functools.wraps(func) in the decorator to preserve the original function's metadata, including its __name__ and docstring. Without it, the name of our decorated greet function would appear as wrapper.
Getting Names of Other Objects (Classes and Modules)
The __name__ attribute is not limited to functions. It is a standard attribute for many other Python objects, including classes and modules.
Solution:
import os
class MyCar:
pass
# Get the name of a class
print(f"Class name: {MyCar.__name__}")
# Get the name of an imported module
print(f"Module name: {os.__name__}")
Output:
Class name: MyCar
Module name: os
A Note on the Main Module (__name__ == '__main__')
A special and very important use of the __name__ attribute is the if __name__ == '__main__': block.
- When you run a Python script directly, the interpreter sets the
__name__attribute for that script to the special string"__main__". - When a script is imported by another script, its
__name__is set to its own filename (without the.pyextension).
This allows you to write code that only runs when the file is executed as the main program, but not when it is imported as a module.
Example
my_script.py file content:
def some_function():
print("This is a reusable function.")
print(f"This script's __name__ is: {__name__}")
if __name__ == '__main__':
print("This script was run directly!")
some_function()
Running my_script.py directly:
python my_script.py
Output:
This script's __name__ is: __main__
This script was run directly!
This is a reusable function.
Running another script that imports my_script.py:
# importer.py
import my_script
print("--- Running importer.py ---")
my_script.some_function()
python importer.py
Output:
This script's __name__ is: my_script
--- Running importer.py ---
This is a reusable function.
Conclusion
| To get the name of a... | Use this attribute |
|---|---|
| Function | my_function.__name__ |
| Class | MyClass.__name__ |
| Module | my_module.__name__ |
Accessing the __name__ attribute is the standard, built-in way to get the name of a function or other object in Python. It is a powerful tool for introspection, debugging, and controlling script execution.