W Pythonie, jak uzyskać nazwę funkcji jako ciąg, bez wywoływania funkcji?
def my_function():
pass
print get_function_name_as_string(my_function) # my_function is not in quotes
powinien wyjść "my_function"
.
Czy taka funkcja jest dostępna w Pythonie? Jeśli nie, jakieś pomysły dotyczące implementacji get_function_name_as_string
w Pythonie?
Odpowiedzi:
Używanie
__name__
jest preferowaną metodą, ponieważ stosuje się równomiernie. W przeciwieństwie dofunc_name
tego działa również na wbudowanych funkcjach:Również podwójne podkreślenia wskazują czytelnikowi, że jest to specjalny atrybut. Jako bonus, klasy i moduły również mają
__name__
atrybut, więc pamiętasz tylko jedną specjalną nazwę.źródło
def wrapper(kwargs): super(ExtendedClass,self).call('wrapper', kwargs)
. Masz innego wyboru, czyli:def wrapper(kwargs): super(ExtendedClass,self).call(sys._getframe().f_code.co_name, kwargs)
. Odpowiedź Alberta Vonpuppa wygląda więc dla mnie lepiej.f.__name__ == 'f'
.Aby uzyskać nazwę bieżącej funkcji lub metody z jej wnętrza, rozważ:
sys._getframe
działa również zamiastinspect.currentframe
tego ostatniego, chociaż unika dostępu do funkcji prywatnej.Aby zamiast tego uzyskać nazwę funkcji wywołującej, rozważ
f_back
jak winspect.currentframe().f_back.f_code.co_name
.Jeśli używasz
mypy
, możesz narzekać, że:Aby ukryć powyższy błąd, rozważ:
źródło
sys._getframe
- jest on bezpośrednio połączony z wewnętrznymi elementami CPython.sys._getframe(1).f_code.co_name
, abyś mógł zdefiniować funkcję podobnąget_func_name()
i oczekiwać uzyskania żądanej nazwy funkcji, która ją wywołała.Istnieją również inne zabawne właściwości funkcji. Wpisz,
dir(func_name)
aby je wyświetlić.func_name.func_code.co_code
to skompilowana funkcja przechowywana jako ciąg.wyświetli kod w prawie czytelnej formie. :)
źródło
__names__
są prywatne,__names
są wyjątkowe._names
prywatne (pojedyncze podkreślenie przed, tylko konwencja),__names__
wyjątkowe (podwójne podkreślenia przed i po). Nie jestem pewien, czy podwójne podkreślenie wcześniej ma jakieś znaczenie, formalnie czy jako konwencja.func_name
już nie istnieje w Python3, więc musisz użyć,func.__name__
jeśli chcesz kompatybilnościTa funkcja zwróci nazwę funkcji dzwoniącego.
To jest jak odpowiedź Alberta Vonpuppa z przyjaznym opakowaniem.
źródło
Jeśli interesują Cię również metody klasowe, Python 3.3+ ma
__qualname__
dodatkowo__name__
.źródło
Lubię używać dekoratora funkcji. Dodałem klasę, która również razy czas funkcji. Załóżmy, że gLog to standardowy program rejestrujący w języku Python:
więc teraz wszystko, co musisz zrobić z funkcją, to udekorować ją i voila
źródło
sys._getframe()
nie gwarantuje się, że będzie dostępny we wszystkich implementacjach Pythona ( patrz odnośnik ), możesz użyćtraceback
modułu, aby zrobić to samo, np.Wezwanie do
stack[-1]
zwróci bieżące szczegóły procesu.źródło
sys._getframe()
jest niezdefiniowany,traceback.extract_stack
to również nie działa. Ten ostatni zapewnia zgrubny nadzór nad funkcjonalnością pierwszego; nie możesz oczekiwać, że zobaczysz jedno bez drugiego. W rzeczywistości w IronPython 2.7extract_stack()
zawsze powraca[]
. -1gdzie
stos () [0] rozmówcy
stack () [3] nazwa ciągu metody
źródło
stack()[0]
zawsze będzie wywołujący,[3]
nazwa ciągu metody.Jako rozszerzenie odpowiedzi @ Demyn stworzyłem niektóre funkcje narzędziowe, które wypisują nazwę bieżącej funkcji i jej argumenty:
źródło
Chcesz tylko uzyskać nazwę funkcji tutaj jest to prosty kod do tego. powiedzmy, że masz zdefiniowane te funkcje
wyjście będzie funkcją 1
Powiedzmy, że masz te funkcje na liście
aby uzyskać nazwę funkcji
wyjście będzie
funkcja1
funkcja2
funkcja3
źródło
Widziałem kilka odpowiedzi, które wykorzystywały dekoratorów, choć czułem, że kilka było trochę gadatliwych. Oto coś, czego używam do rejestrowania nazw funkcji, a także ich odpowiednich wartości wejściowych i wyjściowych. Zaadaptowałem to tutaj, aby po prostu wydrukować informacje, zamiast tworzyć plik dziennika, i dostosowałem go do zastosowania w konkretnym przykładzie PO.
Wynik:
źródło
debug
funkcję, gdy tylko możesz ją dodać, po prostu dodając dekorator do dowolnej funkcji, której potrzebujesz lub chcesz wydrukować nazwę funkcji. To wydaje się najłatwiejsze i najbardziej elastyczne.