[python] Determine function name from within that function (without using traceback)

In Python, without using the traceback module, is there a way to determine a function's name from within that function?

Say I have a module foo with a function bar. When executing foo.bar(), is there a way for bar to know bar's name? Or better yet, foo.bar's name?

#foo.py  
def bar():
    print "my name is", __myname__ # <== how do I calculate this at runtime?

This question is related to python function introspection traceback

The answer is


I suggest not to rely on stack elements. If someone use your code within different contexts (python interpreter for instance) your stack will change and break your index ([0][3]).

I suggest you something like that:

class MyClass:

    def __init__(self):
        self.function_name = None

    def _Handler(self, **kwargs):
        print('Calling function {} with parameters {}'.format(self.function_name, kwargs))
        self.function_name = None

    def __getattr__(self, attr):
        self.function_name = attr
        return self._Handler


mc = MyClass()
mc.test(FirstParam='my', SecondParam='test')
mc.foobar(OtherParam='foobar')

functionNameAsString = sys._getframe().f_code.co_name

I wanted a very similar thing because I wanted to put the function name in a log string that went in a number of places in my code. Probably not the best way to do that, but here's a way to get the name of the current function.


I do my own approach used for calling super with safety inside multiple inheritance scenario (I put all the code)

def safe_super(_class, _inst):
    """safe super call"""
    try:
        return getattr(super(_class, _inst), _inst.__fname__)
    except:
        return (lambda *x,**kx: None)


def with_name(function):
    def wrap(self, *args, **kwargs):
        self.__fname__ = function.__name__
        return function(self, *args, **kwargs)
return wrap

sample usage:

class A(object):

    def __init__():
        super(A, self).__init__()

    @with_name
    def test(self):
        print 'called from A\n'
        safe_super(A, self)()

class B(object):

    def __init__():
        super(B, self).__init__()

    @with_name
    def test(self):
        print 'called from B\n'
        safe_super(B, self)()

class C(A, B):

    def __init__():
        super(C, self).__init__()

    @with_name
    def test(self):
        print 'called from C\n'
        safe_super(C, self)()

testing it :

a = C()
a.test()

output:

called from C
called from A
called from B

Inside each @with_name decorated method you have access to self.__fname__ as the current function name.


import inspect

def whoami():
    return inspect.stack()[1][3]

def whosdaddy():
    return inspect.stack()[2][3]

def foo():
    print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())
    bar()

def bar():
    print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())

foo()
bar()

In IDE the code outputs

hello, I'm foo, daddy is

hello, I'm bar, daddy is foo

hello, I'm bar, daddy is


import inspect

def foo():
   print(inspect.stack()[0][3])
   print(inspect.stack()[1][3]) #will give the caller of foos name, if something called foo

I recently tried to use the above answers to access the docstring of a function from the context of that function but as the above questions were only returning the name string it did not work.

Fortunately I found a simple solution. If like me, you want to refer to the function rather than simply get the string representing the name you can apply eval() to the string of the function name.

import sys
def foo():
    """foo docstring"""
    print(eval(sys._getframe().f_code.co_name).__doc__)

Here's a future-proof approach.

Combining @CamHart's and @Yuval's suggestions with @RoshOxymoron's accepted answer has the benefit of avoiding:

  • _hidden and potentially deprecated methods
  • indexing into the stack (which could be reordered in future pythons)

So I think this plays nice with future python versions (tested on 2.7.3 and 3.3.2):

from __future__ import print_function
import inspect

def bar():
    print("my name is '{}'".format(inspect.currentframe().f_code.co_name))

Use __name__ attribute:

# foo.py
def bar():
    print(f"my name is {bar.__name__}")

You can easily access function's name from within the function using __name__ attribute.

>>> def bar():
...     print(f"my name is {bar.__name__}")
...
>>> bar()
my name is bar

I've come across this question myself several times, looking for the ways to do it. Correct answer is contained in the Python's documentation (see Callable types section).

Every function has a __name__ parameter that returns its name and even __qualname__ parameter that returns its full name, including which class it belongs to (see Qualified name).


You can get the name that it was defined with using the approach that @Andreas Jung shows, but that may not be the name that the function was called with:

import inspect

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

Foo2 = Foo

>>> Foo()
Foo

>>> Foo2()
Foo

Whether that distinction is important to you or not I can't say.


I guess inspect is the best way to do this. For example:

import inspect
def bar():
    print("My name is", inspect.stack()[0][3])

print(inspect.stack()[0].function) seems to work too (Python 3.5).


You can use a decorator:

def my_function(name=None):
    return name

def get_function_name(function):
    return function(name=function.__name__)

>>> get_function_name(my_function)
'my_function'

import sys

def func_name():
    """
    :return: name of caller
    """
    return sys._getframe(1).f_code.co_name

class A(object):
    def __init__(self):
        pass
    def test_class_func_name(self):
        print(func_name())

def test_func_name():
    print(func_name())

Test:

a = A()
a.test_class_func_name()
test_func_name()

Output:

test_class_func_name
test_func_name

This is actually derived from the other answers to the question.

Here's my take:

import sys

# for current func name, specify 0 or no argument.
# for name of caller of current func, specify 1.
# for name of caller of caller of current func, specify 2. etc.
currentFuncName = lambda n=0: sys._getframe(n + 1).f_code.co_name


def testFunction():
    print "You are in function:", currentFuncName()
    print "This function's caller was:", currentFuncName(1)    


def invokeTest():
    testFunction()


invokeTest()

# end of file

The likely advantage of this version over using inspect.stack() is that it should be thousands of times faster [see Alex Melihoff's post and timings regarding using sys._getframe() versus using inspect.stack() ].


There are a few ways to get the same result:

from __future__ import print_function
import sys
import inspect

def what_is_my_name():
    print(inspect.stack()[0][0].f_code.co_name)
    print(inspect.stack()[0][3])
    print(inspect.currentframe().f_code.co_name)
    print(sys._getframe().f_code.co_name)

Note that the inspect.stack calls are thousands of times slower than the alternatives:

$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][0].f_code.co_name'
1000 loops, best of 3: 499 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][3]'
1000 loops, best of 3: 497 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.currentframe().f_code.co_name'
10000000 loops, best of 3: 0.1 usec per loop
$ python -m timeit -s 'import inspect, sys' 'sys._getframe().f_code.co_name'
10000000 loops, best of 3: 0.135 usec per loop

This is pretty easy to accomplish with a decorator.

>>> from functools import wraps

>>> def named(func):
...     @wraps(func)
...     def _(*args, **kwargs):
...         return func(func.__name__, *args, **kwargs)
...     return _
... 

>>> @named
... def my_func(name, something_else):
...     return name, something_else
... 

>>> my_func('hello, world')
('my_func', 'hello, world')

I found a wrapper that will write the function name

from functools import wraps

def tmp_wrap(func):
    @wraps(func)
    def tmp(*args, **kwargs):
        print func.__name__
        return func(*args, **kwargs)
    return tmp

@tmp_wrap
def my_funky_name():
    print "STUB"

my_funky_name()

This will print

my_funky_name

STUB


I keep this handy utility nearby:

import inspect
myself = lambda: inspect.stack()[1][3]

Usage:

myself()

I am not sure why people make it complicated:

import sys 
print("%s/%s" %(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name))

Examples related to python

programming a servo thru a barometer Is there a way to view two blocks of code from the same file simultaneously in Sublime Text? python variable NameError Why my regexp for hyphenated words doesn't work? Comparing a variable with a string python not working when redirecting from bash script is it possible to add colors to python output? Get Public URL for File - Google Cloud Storage - App Engine (Python) Real time face detection OpenCV, Python xlrd.biffh.XLRDError: Excel xlsx file; not supported Could not load dynamic library 'cudart64_101.dll' on tensorflow CPU-only installation

Examples related to function

$http.get(...).success is not a function Function to calculate R2 (R-squared) in R How to Call a Function inside a Render in React/Jsx How does Python return multiple values from a function? Default optional parameter in Swift function How to have multiple conditions for one if statement in python Uncaught TypeError: .indexOf is not a function Proper use of const for defining functions in JavaScript Run php function on button click includes() not working in all browsers

Examples related to introspection

Using isKindOfClass with Swift Get all object attributes in Python? Determine function name from within that function (without using traceback) Ruby: kind_of? vs. instance_of? vs. is_a? Get model's fields in Django How to get the caller's method name in the called method? How to get the name of the current method from code How can I get the name of an object in Python? How do I look inside a Python object? How do I access properties of a javascript object if I don't know the names?

Examples related to traceback

Determine function name from within that function (without using traceback) How to catch and print the full exception traceback without halting/exiting the program? When I catch an exception, how do I get the type, file, and line number? How to exit from Python without traceback? Showing the stack trace from a running Python application