Как получить имя функции или метода из функции или метода Python?

Мне кажется, что я должен это знать, но я не смог понять это...

Я хочу получить имя метода, который является тестом интеграции, изнутри, чтобы он мог распечатать какой-либо диагностический текст. Я могу, конечно, просто жестко закодировать имя метода в строке, но я хотел бы сделать тест немного более сухим, если это возможно.

Ответ 1

Ответы, связанные с интроспекцией через inspect и тому подобное, являются разумными. Но может быть другой вариант, в зависимости от вашей ситуации:

Если ваш тест интеграции написан с помощью модуля unittest, вы можете использовать self.id() в своей тестовой камере.

Ответ 2

Это, пожалуй, самый простой способ с помощью модуля inspect:

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

Вы можете обобщить это с помощью:

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

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

Кредит Stefaan Lippens, который был найден через google.

Ответ 3

Этот декоратор делает имя метода доступным внутри функции, передавая его как аргумент ключевого слова.

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

Вы использовали бы его так:

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

print sum(2, 4)

Но, может быть, вы захотите написать то, что хотите прямо внутри самого декоратора. Затем код является примером способа получить имя функции в декораторе. Если вы дадите более подробную информацию о том, что вы хотите сделать в функции, для которой требуется имя, возможно, я могу предложить что-то еще.

Ответ 4

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

Вывод:

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

Используйте "назад = 1", чтобы найти информацию о двух уровнях, отступающих от стека, и т.д.

Ответ 5

Я думаю, что модуль traceback может иметь то, что вы ищете. В частности, функция extract_stack выглядит так, как будто она выполнит задание.