Как я могу получить имя функции или метода из функции или метода Python? - PullRequest
41 голосов
/ 29 октября 2008

Я чувствую, что должен это знать, но я не смог понять ...

Я хочу получить название метода - который является интегральным тестом - изнутри, чтобы он мог распечатать некоторый диагностический текст. Конечно, я могу просто жестко закодировать имя метода в строке, но я бы хотел сделать тест немного более СУХИМЫМ, если это возможно.

Ответы [ 5 ]

55 голосов
/ 29 октября 2008

Это самый простой способ использования модуля 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.

23 голосов
/ 29 октября 2008

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

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

16 голосов
/ 29 октября 2008

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

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)

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

10 голосов
/ 29 октября 2008
# 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", чтобы найти информацию о двух уровнях обратно в стек и т. Д.

3 голосов
/ 29 октября 2008

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...