2008-10-28 11 views
39

Siento que debería saber esto, pero no he podido averiguarlo ...¿Cómo obtengo el nombre de una función o método dentro de una función o método de Python?

Quiero obtener el nombre de un método, que es una prueba de integración, desde dentro para que pueda imprimir algún texto de diagnóstico. Puedo, por supuesto, codificar el nombre del método en la cadena, pero me gustaría hacer la prueba un poco más SECA si es posible.

+0

posible duplicado de [¿Cómo obtener el nombre de la función como cadena en Python?] (Http://stackoverflow.com/questions/251464/how-to-get-the-function-name-as-string-in- python) – DarenW

+0

@DarenW No lo es. Solicitar el nombre de una función desde una variable que contiene un objeto de función y solicitar el nombre de una función desde adentro son dos preguntas muy diferentes. –

Respuesta

23

Las respuestas que implican la introspección a través de inspect y similares son razonables . Pero puede haber otra opción, dependiendo de su situación:

Si su prueba de integración está escrita con el módulo unittest, puede usar self.id() dentro de su TestCase.

+1

Acabo de descubrir que self.id() funciona en el método unittest setUp() (devuelve el nombre de la prueba, no "setUp"), a diferencia de las otras soluciones. Por lo tanto, estoy cambiando esto a la respuesta aceptada para esta pregunta en particular. –

+0

@DarylSpitzer ¡agradable! – Dan

3

Creo que el módulo traceback puede tener lo que estás buscando. En particular, la función extract_stack parece que hará el trabajo.

16

Este decorador pone el nombre del método disponible dentro de la función pasándolo como un argumento de palabra clave.

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 

que usaría esta manera:

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

print sum(2, 4) 

Pero tal vez te gustaría escribir lo que desea directamente en el interior del mismo decorador. Entonces, el código es un ejemplo de una forma de obtener el nombre de la función en un decorador. Si proporciona más detalles sobre lo que desea hacer en la función, eso requiere el nombre, tal vez pueda sugerir algo más.

+2

+1 en el uso de un decorador sobre confiar en los detalles de implementación –

+1

@MatthewTrevor Para ser sincero, veo un decorador que confía en los detalles de implementación. De acuerdo con http://stackoverflow.com/questions/251464/how-to-get-a-function-name-as-a-string-in-python, debería ser mejor usar '.__ name__' sobre' .func_name' . Estoy de acuerdo con la idea básica, sin embargo. –

53

Esta parece ser la forma más sencilla utilizando el módulo inspect:

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

Usted puede generalizar esto con:

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

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

crédito a Stefaan Lippens que fue encontrado a través de Google.

+0

Typo: el nombre debería ser "Stefaan". El enlace es antiguo y no funciona, prueba "http://stefaanlippens.net/python_inspect". –

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

Salida:

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

uso "de vuelta = 1" para encontrar información con respecto a dos niveles hacia abajo la pila, etc.

Cuestiones relacionadas