2008-10-28 11 views
39

Czuję, że powinienem to wiedzieć, ale nie byłem w stanie tego rozgryźć ...Jak uzyskać nazwę funkcji lub metody z funkcji lub metody Pythona?

Chcę uzyskać nazwę metody - która jest testem integracji - od wewnątrz to może wydrukować jakiś tekst diagnostyczny. Mogę, oczywiście, po prostu zakodować nazwę metody w łańcuchu, ale chciałbym, aby test był bardziej SUCHY, jeśli to możliwe.

+0

możliwy duplikat [Jak uzyskać nazwę funkcji jako ciąg w języku Python?] (Http://stackoverflow.com/questions/251464/how-to-get-the-function-name-as- string-in- python) – DarenW

+0

@DarenW Nie jest. Żądanie nazwy funkcji ze zmiennej zawierającej obiekt funkcji i żądanie nazwy funkcji od wewnątrz to dwa bardzo różne pytania. –

Odpowiedz

23

Odpowiedzi udziałem introspekcji poprzez inspect i tym podobne są uzasadnione . Ale może być inna opcja, w zależności od twojej sytuacji:

Jeśli twój test integracji jest napisany z modułem unittest, możesz użyć self.id() w swojej TestCase.

+1

Właśnie odkryłem, że self.id() działa w metodach unitest setUp() (zwraca nazwę testu, a nie "setUp"), w przeciwieństwie do innych rozwiązań. Dlatego zmienię to na akceptowaną odpowiedź na to konkretne pytanie. –

+0

@DarylSpitzer nice! – Dan

3

Myślę, że moduł traceback może mieć to, czego szukasz. W szczególności funkcja extract_stack wygląda na to, że wykona to zadanie.

16

Ten dekorator udostępnia nazwę metody w funkcji, przekazując ją jako argument słowa kluczowego.

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 

będzie go używać w ten sposób:

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

print sum(2, 4) 

Ale może tylko chcesz napisać co chcesz bezpośrednio wewnątrz samego dekoratora. Następnie kod jest przykładem sposobu na uzyskanie nazwy funkcji w dekoratorze. Jeśli podasz więcej szczegółów na temat tego, co chcesz zrobić w funkcji, która wymaga nazwy, może mogę zasugerować coś innego.

+2

+1 na temat korzystania z dekoratora polegającego na powoływaniu się na szczegóły implementacji –

+1

@MatthewTrevor Szczerze mówiąc widzę dekoratora, który opiera się na szczegółach implementacji. Zgodnie z http://stackoverflow.com/questions/251464/how-to-get-a-function-name-as-a-string-in-python powinno być lepiej użyć '.__ name__' zamiast' .func_name' . Zgadzam się jednak z podstawową ideą. –

53

To wydaje się być najprostszym sposobem, za pomocą modułu inspect:

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

Można uogólnić to z:

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

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

zgłosił Stefaan Lippens który został znaleziony przez google.

+0

Literówka: nazwa powinna brzmieć "Stefaan". Link jest stary i nie działa - spróbuj "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() 

wyjściowa:

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

Use "back = 1", aby znaleźć informacje dotyczące dwa poziomy z powrotem w dół stosu, itp

Powiązane problemy