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

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

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

foo()

output:

foo
<module_caller_of_foo>

Python doesnt have a feature to access the function or its name within the function itself. It has been proposed but rejected. If you dont want to play with the stack yourself, you should either use bar or bar.__name__ depending on context.

The given rejection notice is:

This PEP is rejected. It is not clear how it should be implemented or what the precise semantics should be in edge cases, and there arent enough important use cases given. response has been lukewarm at best.

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

There are few ways to get the same result:

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

Update 08/2021 (original post was written for Python2.7)

Python 3.9.1 (default, Dec 11 2020, 14:32:07)
[GCC 7.3.0] :: Anaconda, Inc. on linux

python -m timeit -s import inspect, sys inspect.stack()[0][0].f_code.co_name
500 loops, best of 5: 390 usec per loop
python -m timeit -s import inspect, sys inspect.stack()[0][3]
500 loops, best of 5: 398 usec per loop
python -m timeit -s import inspect, sys inspect.currentframe().f_code.co_name
2000000 loops, best of 5: 176 nsec per loop
python -m timeit -s import inspect, sys sys._getframe().f_code.co_name
5000000 loops, best of 5: 62.8 nsec per loop

Leave a Reply

Your email address will not be published. Required fields are marked *