Explain Codes LogoExplain Codes Logo

How to get a function name as a string?

python
meta-programming
reflection
debugging
Anton ShumikhinbyAnton Shumikhin·Dec 6, 2024
TLDR

Retrieve a function's name as a string in Python with the __name__ attribute:

function_name = my_function.__name__

This syntax proves effective for any callable, such as my_function.

Diving deeper: Understanding the __name__ attribute

Playing detective with inspect module

Don't we all like some detective work? Start by importing the inspect module, which is a fancy tool for anything introspective in Python:

import inspect
  • To identify the running function, piece together inspect.currentframe().f_back.f_code:
current_function_name = inspect.currentframe().f_back.f_code.co_name # It's like The Inception movie: a function within a function...
  • Using type checkers? Avoid the "Stop! Who are you?" line from them:
from types import FrameType from typing import cast current_function_name = cast(FrameType, inspect.currentframe()).f_code.co_name # Avoid mypy nagging like a grumpy old man

A word of caution

Private functions like sys._getframe() are like a "Stay out!" sign. Respect it as it's meant for Python internals and not intended to be messed with.

What's in a name? Introducing __qualname__

Sometimes, a function is social and has family ties. In Python 3.3+ use __qualname__ for the fully qualified name, which is useful for methods within classes:

class MyClass: def my_method(self): pass method_name = MyClass.my_method.__qualname__ # It's like calling 'Uncle Bob' instead of just 'Bob'

Reflections, not the mirror kind: Meta-programming

Python lets you take a leap to self-awareness. Let's explore some reflection techniques to probe deeper:

attributes = dir(my_function) # Grabs the function's ID, keys, passport... you get it!
  • Curious about the bytecode? Note that __code__.co_code usage can be highly complex.
  • The dis module can show the sequel to your function's story - the bytecode instructions it runs:
import dis dis.dis(my_function) # It's like seeing The Matrix code, but without the cool green light

Know your trash: Deprecated methods

Remember that func_name is like the Internet Explorer of function name retrieval. You're in the age of __name__ now!

Built to function: Built-in functions

Built-in functions have names too, and they are not shy about it:

print.__name__ # 'print' # Even the silent ones can say their name

Why bother with function names?

An equation without a variable is worthless. Similarly, understanding a function's name helps clarify the problem and the solution.

Why should you care for function names?

Why does getting the name matter? It's essential for a few cool reasons:

  • Debugging: It acts as a trail of breadcrumbs when tracing execution flow.
  • Decorators: Useful when a decorator logs the decorated function's name.
  • Dynamic Function Calls: When you want to get all Mission Impossible with your code and run functions by name obtained through an API or user input.

Advanced magic with function names

Function names come handy when working on advanced patterns like dependency injection, plugins, or popular frameworks like Flask or Django.

You shall not pass: Common pitfalls

Don't fall into the trap! Be cautious with __name__ in an environment where functions can be renamed or wrapped – like Hogwarts, it's full of secrets!