Getting the caller function name inside another function in Python?

PythonDebugging

Python Problem Overview


If you have 2 functions like:

def A
def B

and A calls B, can you get who is calling B inside B, like:

def A () :
    B ()

def B () :
    this.caller.name

Python Solutions


Solution 1 - Python

You can use the inspect module to get the info you want. Its stack method returns a list of frame records.

  • For Python 2 each frame record is a list. The third element in each record is the caller name. What you want is this:

     >>> import inspect
     >>> def f():
     ...     print inspect.stack()[1][3]
     ...
     >>> def g():
     ...     f()
     ...
     >>> g()
     g
    

  • For Python 3.5+, each frame record is a named tuple so you need to replace

     print inspect.stack()[1][3]
    

    with

     print(inspect.stack()[1].function)
    

    on the above code.

Solution 2 - Python

There are two ways, using sys and inspect modules:

  • sys._getframe(1).f_code.co_name
  • inspect.stack()[1][3]

The stack() form is less readable and is implementation dependent since it calls sys._getframe(), see extract from inspect.py:

def stack(context=1):
    """Return a list of records for the stack above the caller's frame."""
    return getouterframes(sys._getframe(1), context)

Solution 3 - Python

Note (June 2018): today, I would probably use inspect module, see other answers

sys._getframe(1).f_code.co_name like in the example below:

>>> def foo():
...  global x
...  x = sys._getframe(1)
...
>>> def y(): foo()
...
>>> y()
>>> x.f_code.co_name
'y'
>>>  

Important note: as it's obvious from the _getframe method name (hey, it starts with an underscore), it's not an API method one should be thoughtlessly rely on.

Solution 4 - Python

This works for me! :D

>>> def a():
...     import sys
...     print sys._getframe(1).f_code.co_name
...
>>> def b():
...     a()
...
...
>>> b()
b
>>>

Solution 5 - Python

you can user the logging module and specify the %(funcName)s option in BaseConfig()

import logging
logging.basicConfig(filename='/tmp/test.log', level=logging.DEBUG, format='%(asctime)s | %(levelname)s | %(funcName)s |%(message)s')

def A():
    logging.info('info')

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJoan VengeView Question on Stackoverflow
Solution 1 - PythonAyman HouriehView Answer on Stackoverflow
Solution 2 - PythonEricView Answer on Stackoverflow
Solution 3 - PythonPiotr FindeisenView Answer on Stackoverflow
Solution 4 - PythonAlex CoryView Answer on Stackoverflow
Solution 5 - PythonmescalinView Answer on Stackoverflow