How to get a function name as a string?

Posted on

Solving problem is about exposing yourself to as many situations as possible like How to get a function name as a string? and practice these strategies over and over. With time, it becomes second nature and a natural way you approach any problems in general. Big or small, always start with a plan, use other strategies mentioned here till you are confident and ready to code the solution.
In this post, my aim is to share an overview the topic about How to get a function name as a string?, which can be followed any time. Take easy to follow this discuss.

How to get a function name as a string?

In Python, how do I get a function name as a string, without calling the function?

def my_function():
    pass
print get_function_name_as_string(my_function) # my_function is not in quotes

should output "my_function".

Is such function available in Python? If not, any ideas on how to implement get_function_name_as_string, in Python?

Asked By: X10

||

Answer #1:

my_function.__name__

Using __name__ is the preferred method as it applies uniformly. Unlike func_name, it works on built-in functions as well:

>>> import time
>>> time.time.func_name
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'builtin_function_or_method' object has no attribute 'func_name'
>>> time.time.__name__
'time'

Also the double underscores indicate to the reader this is a special attribute. As a bonus, classes and modules have a __name__ attribute too, so you only have remember one special name.

Answered By: user28409

Answer #2:

To get the current function’s or method’s name from inside it, consider:

import inspect
this_function_name = inspect.currentframe().f_code.co_name

sys._getframe also works instead of inspect.currentframe although the latter avoids accessing a private function.

To get the calling function’s name instead, consider f_back as in inspect.currentframe().f_back.f_code.co_name.


If also using mypy, it can complain that:

error: Item “None” of “Optional[FrameType]” has no attribute “f_code”

To suppress the above error, consider:

import inspect
import types
from typing import cast
this_function_name = cast(types.FrameType, inspect.currentframe()).f_code.co_name
Answered By: Albert Vonpupp

Answer #3:

my_function.func_name

There are also other fun properties of functions. Type dir(func_name) to list them. func_name.func_code.co_code is the compiled function, stored as a string.

import dis
dis.dis(my_function)

will display the code in almost human readable format. 🙂

Answered By: Markus Jarderot

Answer #4:

If you’re interested in class methods too, Python 3.3+ has __qualname__ in addition to __name__.

def my_function():
    pass
class MyClass(object):
    def method(self):
        pass
print(my_function.__name__)         # gives "my_function"
print(MyClass.method.__name__)      # gives "method"
print(my_function.__qualname__)     # gives "my_function"
print(MyClass.method.__qualname__)  # gives "MyClass.method"
Answered By: lapis

Answer #5:

This function will return the caller’s function name.

def func_name():
    import traceback
    return traceback.extract_stack(None, 2)[0][2]

It is like Albert Vonpupp’s answer with a friendly wrapper.

Answered By: Demyn

Answer #6:

I like using a function decorator.
I added a class, which also times the function time. Assume gLog is a standard python logger:

class EnterExitLog():
    def __init__(self, funcName):
        self.funcName = funcName
    def __enter__(self):
        gLog.debug('Started: %s' % self.funcName)
        self.init_time = datetime.datetime.now()
        return self
    def __exit__(self, type, value, tb):
        gLog.debug('Finished: %s in: %s seconds' % (self.funcName, datetime.datetime.now() - self.init_time))
def func_timer_decorator(func):
    def func_wrapper(*args, **kwargs):
        with EnterExitLog(func.__name__):
            return func(*args, **kwargs)
    return func_wrapper

so now all you have to do with your function is decorate it and voila

@func_timer_decorator
def my_func():
Answered By: radato

Answer #7:

import inspect
def foo():
   print(inspect.stack()[0][3])

where

  • stack()[0] is the caller

  • stack()[3] is the string name of the method

Answered By: Ma Guowei

Answer #8:

As an extension of @Demyn’s answer, I created some utility functions which print the current function’s name and current function’s arguments:

import inspect
import logging
import traceback
def get_function_name():
    return traceback.extract_stack(None, 2)[0][2]
def get_function_parameters_and_values():
    frame = inspect.currentframe().f_back
    args, _, _, values = inspect.getargvalues(frame)
    return ([(i, values[i]) for i in args])
def my_func(a, b, c=None):
    logging.info('Running ' + get_function_name() + '(' + str(get_function_parameters_and_values()) +')')
    pass
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s [%(levelname)s] -> %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
my_func(1, 3) # 2016-03-25 17:16:06,927 [INFO] -> Running my_func([('a', 1), ('b', 3), ('c', None)])
Answered By: Jim G.

Leave a Reply

Your email address will not be published.