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
In Python, it is possible to pass a function as a argument to another function. Write a function useFunction(func, num) that takes in a function and a number as arguments. The useFunction should produce the output shown in the examples given below.
Python also accepts function recursion, which means a defined function can call itself. Recursion is a common mathematical and programming concept. It means that a function calls itself.
Calling a function from within itself is called recursion and the simple answer is, yes.
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.
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)
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.
This works for me! :D
>>> def a():
... import sys
... print sys._getframe(1).f_code.co_name
...
>>> def b():
... a()
...
...
>>> b()
b
>>>
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')
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With