get current function name inside that function using python
Question:
For my logging purpose i want to log all the names of functions where my code is going
Does not matter who is calling the function , i want the the function name in which i declare this line
import inspect
def whoami():
return inspect.stack()[1][3]
def foo():
print(whoami())
currently it prints foo
, i want to print whoami
Answers:
You probably want inspect.getframeinfo(frame).function
:
import inspect
def whoami():
frame = inspect.currentframe()
return inspect.getframeinfo(frame).function
def foo():
print(whoami())
foo()
prints
whoami
For my logging purpose i want to log all the names of functions where my code is going
Have you considered decorators?
import functools
def logme(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
print(f.__name__)
return f(*args, **kwargs)
return wrapped
@logme
def myfunction():
print("Doing some stuff")
Actually, Eric’s answer points the way if this is about logging:
For my logging purpose i want to log all the names of functions where my code is going
You can adjust the formatter to log the function name:
import logging
def whoami():
logging.info("Now I'm there")
def foo():
logging.info("I'm here")
whoami()
logging.info("I'm back here again")
logging.basicConfig(
format="%(asctime)-15s [%(levelname)s] %(funcName)s: %(message)s",
level=logging.INFO)
foo()
prints
2015-10-16 16:29:34,227 [INFO] foo: I'm here
2015-10-16 16:29:34,227 [INFO] whoami: Now I'm there
2015-10-16 16:29:34,227 [INFO] foo: I'm back here again
Call sys._getframe()
to get a frame
class instance. The f_code.co_name
member holds the function name.
sys._getframe(0).f_code.co_name
Add a simple helper function func_name()
to wrap the call
import sys
def func_name():
return sys._getframe(1).f_code.co_name
def func1():
print(func_name())
func1() # prints 'func1'
This simple reusable method returns a name of the caller/parent function:
def current_method_name():
# [0] is this method's frame, [1] is the parent's frame - which we want
return inspect.stack()[1].function
Example:
def whoami():
print(current_method_name())
whoami()
-> output is whoami
Adding an answer here as it can be useful to include the class name as well as the function.
This checks for self
and cls
convention, to include the class name.
def name_of_caller(frame=1):
"""
Return "class.function_name" of the caller or just "function_name".
"""
frame = sys._getframe(frame)
fn_name = frame.f_code.co_name
var_names = frame.f_code.co_varnames
if var_names:
if var_names[0] == "self":
self_obj = frame.f_locals.get("self")
if self_obj is not None:
return type(self_obj).__name__ + "." + fn_name
if var_names[0] == "cls":
cls_obj = frame.f_locals.get("cls")
if cls_obj is not None:
return cls_obj.__name__ + "." + fn_name
return fn_name
For my logging purpose i want to log all the names of functions where my code is going
Does not matter who is calling the function , i want the the function name in which i declare this line
import inspect
def whoami():
return inspect.stack()[1][3]
def foo():
print(whoami())
currently it prints foo
, i want to print whoami
You probably want inspect.getframeinfo(frame).function
:
import inspect
def whoami():
frame = inspect.currentframe()
return inspect.getframeinfo(frame).function
def foo():
print(whoami())
foo()
prints
whoami
For my logging purpose i want to log all the names of functions where my code is going
Have you considered decorators?
import functools
def logme(f):
@functools.wraps(f)
def wrapped(*args, **kwargs):
print(f.__name__)
return f(*args, **kwargs)
return wrapped
@logme
def myfunction():
print("Doing some stuff")
Actually, Eric’s answer points the way if this is about logging:
For my logging purpose i want to log all the names of functions where my code is going
You can adjust the formatter to log the function name:
import logging
def whoami():
logging.info("Now I'm there")
def foo():
logging.info("I'm here")
whoami()
logging.info("I'm back here again")
logging.basicConfig(
format="%(asctime)-15s [%(levelname)s] %(funcName)s: %(message)s",
level=logging.INFO)
foo()
prints
2015-10-16 16:29:34,227 [INFO] foo: I'm here
2015-10-16 16:29:34,227 [INFO] whoami: Now I'm there
2015-10-16 16:29:34,227 [INFO] foo: I'm back here again
Call sys._getframe()
to get a frame
class instance. The f_code.co_name
member holds the function name.
sys._getframe(0).f_code.co_name
Add a simple helper function func_name()
to wrap the call
import sys
def func_name():
return sys._getframe(1).f_code.co_name
def func1():
print(func_name())
func1() # prints 'func1'
This simple reusable method returns a name of the caller/parent function:
def current_method_name():
# [0] is this method's frame, [1] is the parent's frame - which we want
return inspect.stack()[1].function
Example:
def whoami():
print(current_method_name())
whoami()
-> output is whoami
Adding an answer here as it can be useful to include the class name as well as the function.
This checks for self
and cls
convention, to include the class name.
def name_of_caller(frame=1):
"""
Return "class.function_name" of the caller or just "function_name".
"""
frame = sys._getframe(frame)
fn_name = frame.f_code.co_name
var_names = frame.f_code.co_varnames
if var_names:
if var_names[0] == "self":
self_obj = frame.f_locals.get("self")
if self_obj is not None:
return type(self_obj).__name__ + "." + fn_name
if var_names[0] == "cls":
cls_obj = frame.f_locals.get("cls")
if cls_obj is not None:
return cls_obj.__name__ + "." + fn_name
return fn_name