2008-10-28 9 views
39

Ich fühle mich wie ich das wissen sollte, aber ich konnte es nicht herausfinden ...Wie erhalte ich den Namen einer Funktion oder Methode aus einer Python-Funktion oder -Methode?

Ich möchte den Namen einer Methode - die ein Integrationstest ist - von innen bekommen Es kann also einen Diagnosetext ausdrucken. Ich kann natürlich den Namen der Methode in der Zeichenfolge fest codieren, aber ich möchte den Test ein wenig mehr TROCKEN machen, wenn möglich.

+0

mögliche Duplikate von [Wie bekomme ich den Funktionsnamen als String in Python?] (Http://stackoverflow.com/questions/251464/how-to-get-the-function-name-as-string-in- Python) – DarenW

+0

@DarenW Es ist nicht. Das Anfordern des Namens einer Funktion von einer Variablen, die ein Funktionsobjekt enthält, und das Anfordern des Namens einer Funktion von innen sind zwei sehr unterschiedliche Fragen. –

Antwort

23

Die Antworten beteiligt Selbstbeobachtung über inspect und dergleichen sind angemessen . Je nach Situation gibt es jedoch möglicherweise eine andere Option:

Wenn Ihr Integrationstest mit dem Modul unittest geschrieben wird, können Sie self.id() in Ihrem Testfall verwenden.

+1

Ich habe gerade festgestellt, dass self.id() in der Unittest-Methode setUp() funktioniert (es gibt den Namen des Tests zurück, nicht "setUp" selbst), im Gegensatz zu den anderen Lösungen. Daher ändere ich dies zur akzeptierten Antwort für diese spezielle Frage. –

+0

@DarylSpitzer nett! – Dan

3

Ich denke, das traceback Modul könnte haben, was Sie suchen. Insbesondere sieht die extract_stack-Funktion so aus, als würde sie die Aufgabe erfüllen.

16

Dieser Dekorator gibt den Namen der in der Funktion verfügbaren Methode an, indem er sie als Schlüsselwortargument übergibt.

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 

würden Sie es auf diese Weise verwenden:

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

print sum(2, 4) 

Aber vielleicht würden Sie wollen, schreiben, was Sie direkt in der Dekorateur selbst wollen. Dann ist der Code ein Beispiel für eine Möglichkeit, den Funktionsnamen in einem Decorator zu erhalten. Wenn Sie mehr Details darüber geben, was Sie in der Funktion machen wollen, benötigt das den Namen, vielleicht kann ich etwas anderes vorschlagen.

+2

+1 auf die Verwendung eines Dekorators über die Umsetzung Details –

+1

@MatthewTrevor Um ehrlich zu sein sehe ich einen Dekorateur auf Implementierungsdetails verlassen. Laut http://stackoverflow.com/questions/251464/how-to-get-a-function-name-as-a-string-in-python sollte es besser sein, '.__ name__' über' .func_name' zu ​​verwenden . Ich stimme der Grundidee zu. –

53

Dies scheint der einfachste Weg inspect mit Modul zu sein:

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

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

Credit Stefaan Lippens die über google gefunden:

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

du mit verallgemeinern kann.

+0

Tippfehler: Der Name sollte "Stefaan" sein. Der Link ist alt und funktioniert nicht --- versuchen Sie "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() 

Ausgang:

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

Use "back = 1" finden Informationen in Bezug auf zwei Ebenen zurück in den Stapel usw.

Verwandte Themen