How do I get a function's name as a string?
def foo():
pass
>>> name_of(foo)
"foo"
14 Answers 14
my_function.__name__
Using __name__ is the preferred method as it applies uniformly. Unlike func_name, it works on built-in functions as well:
>>> import time
>>> time.time.func_name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'builtin_function_or_method' object has no attribute 'func_name'
>>> time.time.__name__
'time'
Also the double underscores indicate to the reader this is a special attribute. As a bonus, classes and modules have a __name__ attribute too, so you only have remember one special name.
8 Comments
def wrapper(kwargs): super(ExtendedClass,self).call('wrapper', kwargs). You have another choice, which is: def wrapper(kwargs): super(ExtendedClass,self).call(sys._getframe().f_code.co_name, kwargs). So, the answer from Albert Vonpupp looks better to me.f.__name__ == 'f'.To get the current function's or method's name from inside it, consider:
import inspect
this_function_name = inspect.currentframe().f_code.co_name
sys._getframe also works instead of inspect.currentframe although the latter avoids accessing a private function.
To get the calling function's name instead, consider f_back as in inspect.currentframe().f_back.f_code.co_name.
If also using mypy, it can complain that:
error: Item "None" of "Optional[FrameType]" has no attribute "f_code"
To suppress the above error, consider:
import inspect
import types
from typing import cast
this_function_name = cast(types.FrameType, inspect.currentframe()).f_code.co_name
7 Comments
sys._getframe -- it's directly connected to the internals of CPython.sys._getframe(1).f_code.co_name, so you can define a function like get_func_name() and expect to get the desired name of the function who invoked.If you're interested in class methods too, Python 3.3+ has __qualname__ in addition to __name__.
def my_function():
pass
class MyClass(object):
def method(self):
pass
print(my_function.__name__) # gives "my_function"
print(MyClass.method.__name__) # gives "method"
print(my_function.__qualname__) # gives "my_function"
print(MyClass.method.__qualname__) # gives "MyClass.method"
2 Comments
MyClass.prop.fget.__qualname__ gives MyClass.prop.my_function.func_name
There are also other fun properties of functions. Type dir(func_name) to list them. func_name.func_code.co_code is the compiled function, stored as a string.
import dis
dis.dis(my_function)
will display the code in almost human readable format. :)
9 Comments
__names__ are private, __names are special._names are private (single underscore before, just a convention), __names__ are special (double underscores before and after). Not sure if double underscore before has any meaning, formally or as a convention.func_name doesn't exist any more in python3 so you need to use func.__name__ if you want compatibilityimport inspect
def foo():
print(inspect.stack()[0][3])
where
stack()[0]is the callerstack()[3]is the string name of the method
1 Comment
stack()[0] will always be the caller, [3] the string name of the method.This function will return the caller's function name.
def func_name():
import traceback
return traceback.extract_stack(None, 2)[0][2]
It is like Albert Vonpupp's answer with a friendly wrapper.
3 Comments
I like using a function decorator. I added a class, which also times the function time. Assume gLog is a standard python logger:
class EnterExitLog():
def __init__(self, funcName):
self.funcName = funcName
def __enter__(self):
gLog.debug('Started: %s' % self.funcName)
self.init_time = datetime.datetime.now()
return self
def __exit__(self, type, value, tb):
gLog.debug('Finished: %s in: %s seconds' % (self.funcName, datetime.datetime.now() - self.init_time))
def func_timer_decorator(func):
def func_wrapper(*args, **kwargs):
with EnterExitLog(func.__name__):
return func(*args, **kwargs)
return func_wrapper
so now all you have to do with your function is decorate it and voila
@func_timer_decorator
def my_func():
Comments
You just want to get the name of the function here is a simple code for that. let say you have these functions defined
def function1():
print "function1"
def function2():
print "function2"
def function3():
print "function3"
print function1.__name__
the output will be function1
Now let say you have these functions in a list
a = [function1 , function2 , funciton3]
to get the name of the functions
for i in a:
print i.__name__
the output will be
function1
function2
function3
Comments
As an extension of @Demyn's answer, I created some utility functions which print the current function's name and current function's arguments:
import inspect
import logging
import traceback
def get_function_name():
return traceback.extract_stack(None, 2)[0][2]
def get_function_parameters_and_values():
frame = inspect.currentframe().f_back
args, _, _, values = inspect.getargvalues(frame)
return ([(i, values[i]) for i in args])
def my_func(a, b, c=None):
logging.info('Running ' + get_function_name() + '(' + str(get_function_parameters_and_values()) +')')
pass
logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
'%(asctime)s [%(levelname)s] -> %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)
my_func(1, 3) # 2016年03月25日 17:16:06,927 [INFO] -> Running my_func([('a', 1), ('b', 3), ('c', None)])
Comments
sys._getframe() is not guaranteed to be available in all implementations of Python (see ref) ,you can use the traceback module to do the same thing, eg.
import traceback
def who_am_i():
stack = traceback.extract_stack()
filename, codeline, funcName, text = stack[-2]
return funcName
A call to stack[-1] will return the current process details.
1 Comment
sys._getframe() is undefined, then traceback.extract_stack is also inoperable. The latter provides a rough superset of the functionality of the former; you cannot expect to see one without the other. And in fact, in IronPython 2.7 extract_stack() always returns []. -1I've seen a few answers that utilized decorators, though I felt a few were a bit verbose. Here's something I use for logging function names as well as their respective input and output values. I've adapted it here to just print the info rather than creating a log file and adapted it to apply to the OP specific example.
def debug(func=None):
def wrapper(*args, **kwargs):
try:
function_name = func.__func__.__qualname__
except:
function_name = func.__qualname__
return func(*args, **kwargs, function_name=function_name)
return wrapper
@debug
def my_function(**kwargs):
print(kwargs)
my_function()
Output:
{'function_name': 'my_function'}
2 Comments
debug function once you can add the functionality by simply adding the decorator to whatever function you need or want to print the function name. It's seems to be the easiest and the most adaptable.__qualname__ available directly and when it is not?You can get a function's name as a string by using the special __name__ variable.
def my_function():
pass
print(my_function.__name__) # prints "my_function"
3 Comments
__name__ special variable has been a part of the language since at least Python 2.0 (released in 2000) and likely dates as far back as the late 90s.import inspect
def my_first_function():
func_name = inspect.stack()[0][3]
print(func_name) # my_first_function
or:
import sys
def my_second_function():
func_name = sys._getframe().f_code.co_name
print(func_name) # my_second_function
Comments
Try
import sys
fn_name = sys._getframe().f_code.co_name
further reference https://www.oreilly.com/library/view/python-cookbook/0596001673/ch14s08.html
getattr(func, "__name__", str(func))is what I use, in case it's aMock(or some other object) that has no__name__attribute