如何从Python函数或方法中获取函数或方法的名称?

我觉得我应该知道这件事,但我一直没能弄明白……

我想从方法内部获取一个方法的名称——碰巧是一个集成测试——这样它就可以打印出一些诊断文本。当然,我可以在字符串中硬编码方法的名称,但是如果可能的话,我想让测试变得更枯燥一些。


这似乎是使用模块inspect最简单的方法:

1
2
3
import inspect
def somefunc(a,b,c):
    print"My name is: %s" % inspect.stack()[0][3]

你可以这样概括:

1
2
3
4
5
def funcname():
    return inspect.stack()[1][3]

def somefunc(a,b,c):
    print"My name is: %s" % funcname()

感谢通过谷歌发现的Stefaan Lippens。


通过inspect和类似方法进行内省的答案是合理的。但根据你的情况,可能还有另一种选择:

如果您的集成测试是用unittest模块编写的,那么您可以在您的测试用例中使用self.id()


这个装饰器将方法名作为关键字参数传递,从而使方法名在函数中可用。

1
2
3
4
5
6
7
8
from functools import wraps
def pass_func_name(func):
   "Name of decorated function will be passed as keyword arg _func_name"
    @wraps(func)
    def _pass_name(*args, **kwds):
        kwds['_func_name'] = func.func_name
        return func(*args, **kwds)
    return _pass_name

你可以这样用:

1
2
3
4
5
6
@pass_func_name
def sum(a, b, _func_name):
    print"running function %s" % _func_name
    return a + b

print sum(2, 4)

但也许你想直接在装饰器内部写你想要的东西。然后,代码是在装饰器中获取函数名的方法的一个示例。如果你能给出更多关于你想在函数中做什么的细节,那就需要这个名字,也许我可以给你一些其他的建议。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# file"foo.py"
import sys
import os

def LINE( back = 0 ):
    return sys._getframe( back + 1 ).f_lineno
def FILE( back = 0 ):
    return sys._getframe( back + 1 ).f_code.co_filename
def FUNC( back = 0):
    return sys._getframe( back + 1 ).f_code.co_name
def WHERE( back = 0 ):
    frame = sys._getframe( back + 1 )
    return"%s/%s %s()" % ( os.path.basename( frame.f_code.co_filename ),    
                            frame.f_lineno, frame.f_code.co_name )

def testit():
   print"Here in %s, file %s, line %s" % ( FUNC(), FILE(), LINE() )
   print"WHERE says '%s'" % WHERE()

testit()

输出:

1
2
3
$ python foo.py
Here in testit, file foo.py, line 17
WHERE says 'foo.py/18 testit()'

使用"back = 1"来查找关于堆栈下两层的信息,等等。


我认为traceback模块可能具有您正在寻找的内容。特别是,extract_stack函数看起来可以完成这项工作。