2008-10-28 19 views
39

Mi sento come se dovessi saperlo, ma non sono stato in grado di capirlo ...Come posso ottenere il nome di una funzione o un metodo da una funzione o un metodo Python?

Voglio ottenere il nome di un metodo - che risulta essere un test di integrazione - dall'interno così può stampare del testo diagnostico. Posso, ovviamente, limitarmi a digitare il nome del metodo nella stringa, ma mi piacerebbe rendere il test un po 'più ASCIUTTO se possibile.

+0

possibile duplicato di [Come ottenere il nome della funzione come stringa in Python?] (Http://stackoverflow.com/questions/251464/how-to-get-the-function-name-as-string-in- python) – DarenW

+0

@DarenW Non lo è. Richiedere il nome di una funzione da una variabile contenente un oggetto funzione e richiedere il nome di una funzione dall'interno sono due domande molto diverse. –

risposta

23

Le risposte che coinvolgono l'introspezione tramite inspect e simili sono ragionevoli . Ma potrebbe esserci un'altra opzione, a seconda della situazione:

Se il test di integrazione è scritto con il modulo unittest, è possibile utilizzare self.id() all'interno del proprio TestCase.

+1

Ho appena scoperto che self.id() funziona nel metodo unUp setUp() (restituisce il nome del test, non "setUp" stesso), a differenza delle altre soluzioni. Pertanto, sto cambiando questo alla risposta accettata per questa particolare domanda. –

+0

@DarylSpitzer bello! – Dan

3

Penso che il modulo potrebbe avere quello che stai cercando. In particolare, la funzione extract_stack sembra fare il lavoro.

16

Questo decoratore rende il nome del metodo disponibile all'interno della funzione passandolo come argomento della parola chiave.

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 

si può usare in questo modo:

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

print sum(2, 4) 

Ma forse che ci si vuole scrivere quello che volete direttamente all'interno del decoratore di per sé. Quindi il codice è un esempio di come ottenere il nome della funzione in un decoratore. Se dai maggiori dettagli su cosa vuoi fare nella funzione, che richiede il nome, forse posso suggerire qualcos'altro.

+2

+1 sull'utilizzo di un decoratore basandosi sui dettagli di implementazione –

+1

@MatthewTrevor Per essere onesti, vedo un decoratore che si basa sui dettagli di implementazione. Secondo http://stackoverflow.com/questions/251464/how-to-get-a-function-name-as-a-string-in-python dovrebbe essere meglio usare '.__ nome__' su' .func_name' . Sono d'accordo con l'idea di base, però. –

53

questo sembra essere il modo più semplice utilizzando il modulo inspect:

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

Si potrebbe generalizzare questo con:

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

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

credito a Stefaan Lippens che è stato trovato tramite google.

+0

Typo: il nome dovrebbe essere "Stefaan". Il link è vecchio e non funziona --- prova "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() 

uscita:

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

Usa "back = 1" per trovare informazioni per quanto riguarda due livelli giù la pila, ecc

Problemi correlati