Я чувствую, что должен это знать, но я не мог этого понять ...
Я хочу получить имя метода - который является интеграционным тестом - изнутри, чтобы он мог распечатать некоторый диагностический текст. Я могу, конечно, просто жестко закодировать имя метода в строке, но я бы хотел, чтобы тест был более СУХИМ, если это возможно.
@DarenW Это не так. Запрос имени функции из переменной, содержащей объект функции, и запрос имени функции изнутри - это два очень разных вопроса.






Этот декоратор делает имя метода доступным внутри функции, передавая его в качестве аргумента ключевого слова.
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)
Но, возможно, вы захотите написать то, что хотите, прямо внутри самого декоратора. Тогда код является примером способа получить имя функции в декораторе. Если вы дадите более подробную информацию о том, что вы хотите сделать в функции, для которой требуется имя, возможно, я могу предложить что-то еще.
+1 при использовании декоратора вместо того, чтобы полагаться на детали реализации
@MatthewTrevor Если честно, я вижу, что декоратор полагается на детали реализации. Согласно stackoverflow.com/questions/251464/…, лучше использовать .__name__ вместо .func_name. Однако я согласен с основной идеей.
Кажется, это самый простой способ использования модуля 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()
Кредит Стефан Липпенс, который был найден через Google.
# 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()'
Используйте "back = 1", чтобы найти информацию о двух уровнях вниз по стеку и т. д.
Ответы, связанные с самоанализом через inspect и тому подобное, разумны. Но может быть и другой вариант, в зависимости от вашей ситуации:
Если ваш интеграционный тест написан с помощью модуля модульный тест, вы можете использовать self.id() в своем TestCase.
Я только что обнаружил, что self.id () работает в методе unittest setUp () (он возвращает имя теста, а не сам setUp), в отличие от других решений. Поэтому я заменяю это на принятый ответ на этот конкретный вопрос.
возможный дубликат Как получить имя функции в виде строки в Python?