Getting the caller function name inside another function in Python?

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

Answers:

Thank you for visiting the Q&A section on Magenaut. Please note that all the answers may not help you solve the issue immediately. So please treat them as advisements. If you found the post helpful (or not), leave a comment & I’ll get back to you as soon as possible.

Method 1

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.

Method 2

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)

Method 3

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.

Method 4

This works for me! 😀

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

Method 5

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')


All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
0
Would love your thoughts, please comment.x
()
x