In Python, without using the traceback
module, is there a way to determine a function's name from within that function?
Say I have a module foo with a function bar. When executing foo.bar()
, is there a way for bar to know bar's name? Or better yet, foo.bar
's name?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
This question is related to
python
function
introspection
traceback
I suggest not to rely on stack elements. If someone use your code within different contexts (python interpreter for instance) your stack will change and break your index ([0][3]).
I suggest you something like that:
class MyClass:
def __init__(self):
self.function_name = None
def _Handler(self, **kwargs):
print('Calling function {} with parameters {}'.format(self.function_name, kwargs))
self.function_name = None
def __getattr__(self, attr):
self.function_name = attr
return self._Handler
mc = MyClass()
mc.test(FirstParam='my', SecondParam='test')
mc.foobar(OtherParam='foobar')
functionNameAsString = sys._getframe().f_code.co_name
I wanted a very similar thing because I wanted to put the function name in a log string that went in a number of places in my code. Probably not the best way to do that, but here's a way to get the name of the current function.
I do my own approach used for calling super with safety inside multiple inheritance scenario (I put all the code)
def safe_super(_class, _inst):
"""safe super call"""
try:
return getattr(super(_class, _inst), _inst.__fname__)
except:
return (lambda *x,**kx: None)
def with_name(function):
def wrap(self, *args, **kwargs):
self.__fname__ = function.__name__
return function(self, *args, **kwargs)
return wrap
sample usage:
class A(object):
def __init__():
super(A, self).__init__()
@with_name
def test(self):
print 'called from A\n'
safe_super(A, self)()
class B(object):
def __init__():
super(B, self).__init__()
@with_name
def test(self):
print 'called from B\n'
safe_super(B, self)()
class C(A, B):
def __init__():
super(C, self).__init__()
@with_name
def test(self):
print 'called from C\n'
safe_super(C, self)()
testing it :
a = C()
a.test()
output:
called from C
called from A
called from B
Inside each @with_name decorated method you have access to self.__fname__ as the current function name.
import inspect
def whoami():
return inspect.stack()[1][3]
def whosdaddy():
return inspect.stack()[2][3]
def foo():
print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())
bar()
def bar():
print "hello, I'm %s, daddy is %s" % (whoami(), whosdaddy())
foo()
bar()
In IDE the code outputs
hello, I'm foo, daddy is
hello, I'm bar, daddy is foo
hello, I'm bar, daddy is
import inspect
def foo():
print(inspect.stack()[0][3])
print(inspect.stack()[1][3]) #will give the caller of foos name, if something called foo
I recently tried to use the above answers to access the docstring of a function from the context of that function but as the above questions were only returning the name string it did not work.
Fortunately I found a simple solution. If like me, you want to refer to the function rather than simply get the string representing the name you can apply eval() to the string of the function name.
import sys
def foo():
"""foo docstring"""
print(eval(sys._getframe().f_code.co_name).__doc__)
Here's a future-proof approach.
Combining @CamHart's and @Yuval's suggestions with @RoshOxymoron's accepted answer has the benefit of avoiding:
_hidden
and potentially deprecated methodsSo I think this plays nice with future python versions (tested on 2.7.3 and 3.3.2):
from __future__ import print_function
import inspect
def bar():
print("my name is '{}'".format(inspect.currentframe().f_code.co_name))
Use __name__
attribute:
# foo.py
def bar():
print(f"my name is {bar.__name__}")
You can easily access function's name from within the function using __name__
attribute.
>>> def bar():
... print(f"my name is {bar.__name__}")
...
>>> bar()
my name is bar
I've come across this question myself several times, looking for the ways to do it. Correct answer is contained in the Python's documentation (see Callable types section).
Every function has a __name__
parameter that returns its name and even __qualname__
parameter that returns its full name, including which class it belongs to (see Qualified name).
You can get the name that it was defined with using the approach that @Andreas Jung shows, but that may not be the name that the function was called with:
import inspect
def Foo():
print inspect.stack()[0][3]
Foo2 = Foo
>>> Foo()
Foo
>>> Foo2()
Foo
Whether that distinction is important to you or not I can't say.
I guess inspect
is the best way to do this. For example:
import inspect
def bar():
print("My name is", inspect.stack()[0][3])
print(inspect.stack()[0].function)
seems to work too (Python 3.5).
You can use a decorator:
def my_function(name=None):
return name
def get_function_name(function):
return function(name=function.__name__)
>>> get_function_name(my_function)
'my_function'
import sys
def func_name():
"""
:return: name of caller
"""
return sys._getframe(1).f_code.co_name
class A(object):
def __init__(self):
pass
def test_class_func_name(self):
print(func_name())
def test_func_name():
print(func_name())
Test:
a = A()
a.test_class_func_name()
test_func_name()
Output:
test_class_func_name
test_func_name
This is actually derived from the other answers to the question.
Here's my take:
import sys
# for current func name, specify 0 or no argument.
# for name of caller of current func, specify 1.
# for name of caller of caller of current func, specify 2. etc.
currentFuncName = lambda n=0: sys._getframe(n + 1).f_code.co_name
def testFunction():
print "You are in function:", currentFuncName()
print "This function's caller was:", currentFuncName(1)
def invokeTest():
testFunction()
invokeTest()
# end of file
The likely advantage of this version over using inspect.stack() is that it should be thousands of times faster [see Alex Melihoff's post and timings regarding using sys._getframe() versus using inspect.stack() ].
There are a few ways to get the same result:
from __future__ import print_function
import sys
import inspect
def what_is_my_name():
print(inspect.stack()[0][0].f_code.co_name)
print(inspect.stack()[0][3])
print(inspect.currentframe().f_code.co_name)
print(sys._getframe().f_code.co_name)
Note that the inspect.stack
calls are thousands of times slower than the alternatives:
$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][0].f_code.co_name'
1000 loops, best of 3: 499 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.stack()[0][3]'
1000 loops, best of 3: 497 usec per loop
$ python -m timeit -s 'import inspect, sys' 'inspect.currentframe().f_code.co_name'
10000000 loops, best of 3: 0.1 usec per loop
$ python -m timeit -s 'import inspect, sys' 'sys._getframe().f_code.co_name'
10000000 loops, best of 3: 0.135 usec per loop
This is pretty easy to accomplish with a decorator.
>>> from functools import wraps
>>> def named(func):
... @wraps(func)
... def _(*args, **kwargs):
... return func(func.__name__, *args, **kwargs)
... return _
...
>>> @named
... def my_func(name, something_else):
... return name, something_else
...
>>> my_func('hello, world')
('my_func', 'hello, world')
I found a wrapper that will write the function name
from functools import wraps
def tmp_wrap(func):
@wraps(func)
def tmp(*args, **kwargs):
print func.__name__
return func(*args, **kwargs)
return tmp
@tmp_wrap
def my_funky_name():
print "STUB"
my_funky_name()
This will print
my_funky_name
STUB
I keep this handy utility nearby:
import inspect
myself = lambda: inspect.stack()[1][3]
Usage:
myself()
I am not sure why people make it complicated:
import sys
print("%s/%s" %(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name))
Source: Stackoverflow.com