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

时间:2022-12-07 16:00:25

I feel like I should know this, but I haven't been able to figure it out...

我觉得我应该知道这一点,但我无法弄明白......

I want to get the name of a method--which happens to be an integration test--from inside it so it can print out some diagnostic text. I can, of course, just hard-code the method's name in the string, but I'd like to make the test a little more DRY if possible.

我想从内部获取方法的名称 - 恰好是集成测试 - 因此它可以打印出一些诊断文本。当然,我可以在字符串中对方法的名称进行硬编码,但是如果可能的话,我想让测试更加干燥。

5 个解决方案

#1


23  

The answers involving introspection via inspect and the like are reasonable. But there may be another option, depending on your situation:

涉及通过检查等的内省的答案是合理的。但根据您的具体情况,可能还有其他选择:

If your integration test is written with the unittest module, then you could use self.id() within your TestCase.

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

#2


53  

This seems to be the simplest way using module inspect:

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

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

You could generalise this with:

您可以将此概括为:

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

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

Credit to Stefaan Lippens which was found via google.

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

#3


16  

This decorator makes the name of the method available inside the function by passing it as a keyword argument.

此装饰器通过将其作为关键字参数传递,使函数内部的方法名称可用。

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

You would use it this way:

你会这样使用它:

@pass_func_name
def sum(a, b, _func_name):
    print "running function %s" % _func_name
    return a + b

print sum(2, 4)

But maybe you'd want to write what you want directly inside the decorator itself. Then the code is an example of a way to get the function name in a decorator. If you give more details about what you want to do in the function, that requires the name, maybe I can suggest something else.

但也许你想在装饰者本身内直接写出你想要的东西。然后代码是一个在装饰器中获取函数名的方法的示例。如果你提供关于你想在函数中做什么的更多细节,那需要这个名字,也许我可以推荐别的东西。

#4


10  

# 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()

Output:

输出:

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

Use "back = 1" to find info regarding two levels back down the stack, etc.

使用“back = 1”查找关于堆栈等两个级别的信息等。

#5


3  

I think the traceback module might have what you're looking for. In particular, the extract_stack function looks like it will do the job.

我认为追溯模块可能有你想要的东西。特别是,extract_stack函数看起来会完成这项工作。

#1


23  

The answers involving introspection via inspect and the like are reasonable. But there may be another option, depending on your situation:

涉及通过检查等的内省的答案是合理的。但根据您的具体情况,可能还有其他选择:

If your integration test is written with the unittest module, then you could use self.id() within your TestCase.

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

#2


53  

This seems to be the simplest way using module inspect:

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

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

You could generalise this with:

您可以将此概括为:

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

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

Credit to Stefaan Lippens which was found via google.

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

#3


16  

This decorator makes the name of the method available inside the function by passing it as a keyword argument.

此装饰器通过将其作为关键字参数传递,使函数内部的方法名称可用。

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

You would use it this way:

你会这样使用它:

@pass_func_name
def sum(a, b, _func_name):
    print "running function %s" % _func_name
    return a + b

print sum(2, 4)

But maybe you'd want to write what you want directly inside the decorator itself. Then the code is an example of a way to get the function name in a decorator. If you give more details about what you want to do in the function, that requires the name, maybe I can suggest something else.

但也许你想在装饰者本身内直接写出你想要的东西。然后代码是一个在装饰器中获取函数名的方法的示例。如果你提供关于你想在函数中做什么的更多细节,那需要这个名字,也许我可以推荐别的东西。

#4


10  

# 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()

Output:

输出:

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

Use "back = 1" to find info regarding two levels back down the stack, etc.

使用“back = 1”查找关于堆栈等两个级别的信息等。

#5


3  

I think the traceback module might have what you're looking for. In particular, the extract_stack function looks like it will do the job.

我认为追溯模块可能有你想要的东西。特别是,extract_stack函数看起来会完成这项工作。