Wie bekomme ich den Namen einer Funktion als String?
def foo():
pass
>>> name_of(foo)
"foo"
X10
Wie bekomme ich den Namen einer Funktion als String?
def foo():
pass
>>> name_of(foo)
"foo"
my_function.__name__
Verwenden __name__
ist die bevorzugte Methode, da sie einheitlich angewendet wird. nicht wie func_name
es funktioniert auch mit integrierten Funktionen:
>>> import time
>>> time.time.func_name
Traceback (most recent call last):
File "<stdin>", line 1, in ?
AttributeError: 'builtin_function_or_method' object has no attribute 'func_name'
>>> time.time.__name__
'time'
Auch die doppelten Unterstriche weisen den Leser darauf hin, dass es sich um ein besonderes Attribut handelt. Als Bonus haben Klassen und Module a __name__
-Attribut, sodass Sie sich nur einen speziellen Namen merken müssen.
Weil Sie in einigen Fällen ein Funktionsobjekt als Argument für Ihre Funktion erhalten und den Namen dieser Funktion anzeigen/speichern/manipulieren müssen. Vielleicht generieren Sie Dokumentation, Hilfetext, eine Historie von Aktionen usw. Also nein, Sie codieren den Funktionsnamen nicht immer fest.
– mbargiel
26. Juli 2013 um 14:17 Uhr
@mgargiel: Was ich sagen wollte ist: Angenommen, Sie haben eine Klasse, die 100 Methoden definiert, wobei alle Methoden nur Wrapper sind, die eine private Methode aufrufen und den Namen des Wrappers selbst übergeben. Etwas wie das: def wrapper(kwargs): super(ExtendedClass,self).call('wrapper', kwargs)
. Sie haben eine andere Wahl, nämlich: def wrapper(kwargs): super(ExtendedClass,self).call(sys._getframe().f_code.co_name, kwargs)
. Die Antwort von Albert Vonpupp sieht für mich also besser aus.
– Richard Gomes
30. August 2013 um 19:20 Uhr
@RichardGomes Eine Antwort ist geeignet, um den Namen innerhalb der Funktion selbst zu erhalten, die andere ist geeignet, um ihn aus einer Funktionsreferenz zu erhalten. Die geschriebene Frage des OP weist auf Letzteres hin.
– Russell Borogove
31. August 2013 um 0:44 Uhr
@RichardGomes Eigentlich bin ich auf diese Frage gekommen, um nach einer Lösung für dieses Problem zu suchen. Das Problem, das ich zu lösen versuche, ist, einen Decorator zu erstellen, mit dem alle meine Anrufe protokolliert werden können.
– ali-hussain
18. September 2013 um 19:36 Uhr
@RichardGomes-Funktionen sind erstklassige Objekte, an die mehr als nur ein Name gebunden sein kann. Das ist nicht unbedingt der Fall f.__name__ == 'f'
.
– Wim
13. März 2014 um 20:13 Uhr
Albert Vonpupp
Um den Namen der aktuellen Funktion oder Methode daraus abzurufen, beachten Sie Folgendes:
import inspect
this_function_name = inspect.currentframe().f_code.co_name
sys._getframe
funktioniert auch statt inspect.currentframe
obwohl letzteres den Zugriff auf eine private Funktion vermeidet.
Um stattdessen den Namen der aufrufenden Funktion zu erhalten, ziehen Sie in Betracht f_back
wie in inspect.currentframe().f_back.f_code.co_name
.
Wenn auch verwenden mypy
es kann sich beschweren, dass:
error: Item „None“ von „Optional[FrameType]” hat kein Attribut “f_code”
Um den obigen Fehler zu unterdrücken, beachten Sie Folgendes:
import inspect
import types
from typing import cast
this_function_name = cast(types.FrameType, inspect.currentframe()).f_code.co_name
+1: Dies ist die Antwort, die ich gerne sehen würde. Andere Antworten gehen davon aus, dass der Aufrufer den Funktionsnamen bereits kennt, was im Kontext dieser Frage Unsinn ist.
– Richard Gomes
11. Juli 2013 um 16:43 Uhr
Richard: Nein, tut es nicht. SIE gehen davon aus, dass Sie anrufen Name oder func_name für Ihre Funktion direkt im selben Bereich, in dem sie definiert wurde, was sehr oft nicht der Fall ist. Denken Sie daran, dass Funktionen Objekte sind – sie können als Argumente an andere Funktionen weitergegeben, in Listen/Dikten für spätere Suchen oder Ausführung gespeichert werden usw.
– mbargiel
26. Juli 2013 um 14:24 Uhr
@paulus_almighty, das Graben in Stapelrahmen erscheint mir nicht abstrakt! Tatsächlich ist es so etwas wie das Gegenteil von abstrakt. Siehe die Ausführungsdetails Hinweis in den Dokumenten. Nicht alle Implementierungen von Python enthalten sys._getframe
— es ist direkt mit den Interna von CPython verbunden.
– Absender
31. Januar 2016 um 14:42 Uhr
Dies funktioniert nur innerhalb der Funktion, aber die Frage gibt an, dass die Funktion nicht aufgerufen werden soll.
– Benutzer2357112
29. März 2016 um 0:02 Uhr
Falls Sie Ihre Funktion in etwas benutzerfreundlicheres und leichter zu merkendes umwandeln möchten, müssen Sie Frame 1 wie abrufen sys._getframe(1).f_code.co_name
sodass Sie eine Funktion wie definieren können get_func_name()
und erwarten, den gewünschten Namen der aufgerufenen Funktion zu erhalten.
– m3nda
4. Januar 2017 um 10:39 Uhr
Markus Jarderot
my_function.func_name
Es gibt auch andere lustige Eigenschaften von Funktionen. Typ dir(func_name)
sie aufzulisten. func_name.func_code.co_code
ist die kompilierte Funktion, die als Zeichenfolge gespeichert wird.
import dis
dis.dis(my_function)
zeigt den Code in an fast menschenlesbares Format. 🙂
Was ist der Unterschied zwischen f.__name__ und f.funktionsname?
– Federico A. Ramponi
30. Oktober 2008 um 19:43 Uhr
Sam: Namen sind privat, __Namen speziell sind, gibt es einen konzeptionellen Unterschied.
– Matthew Trevor
31. Oktober 2008 um 3:15 Uhr
Falls jemand durch die vorangehende Antwort von Matthew verwirrt ist, hat das Kommentarsystem einige doppelte Unterstriche als Code für Fettdruck interpretiert. Mit Backtick maskiert, sollte die Nachricht lauten: __names__
sind privat, __names
sind besonders.
– gwideman
20. Februar 2014 um 21:34 Uhr
Eigentlich denke ich, dass das Richtige ist _names
sind privat (einfacher Unterstrich davor, nur eine Konvention), __names__
sind speziell (doppelte Unterstriche davor und danach). Ich bin mir nicht sicher, ob der doppelte Unterstrich formell oder als Konvention eine Bedeutung hat.
– MestreLion
23. August 2014 um 8:48 Uhr
func_name
existiert nicht mehr in python3, also müssen Sie verwenden func.__name__
wenn Sie Kompatibilität wünschen
– Daenith
7. April 2017 um 15:50 Uhr
Wenn Sie auch an Klassenmethoden interessiert sind, hat Python 3.3+ dies getan __qualname__
zusätzlich zu __name__
.
def my_function():
pass
class MyClass(object):
def method(self):
pass
print(my_function.__name__) # gives "my_function"
print(MyClass.method.__name__) # gives "method"
print(my_function.__qualname__) # gives "my_function"
print(MyClass.method.__qualname__) # gives "MyClass.method"
Diese Funktion gibt den Funktionsnamen des Aufrufers zurück.
def func_name():
import traceback
return traceback.extract_stack(None, 2)[0][2]
Es ist wie die Antwort von Albert Vonpupp mit einem freundlichen Umschlag.
Ich hatte “
– Emmagras
18. Oktober 2014 um 14:49 Uhr
für mich funktioniert das nicht, aber das funktioniert: traceback.extract_stack()[-1][2]
– mike01010
22. November 2014 um 3:54 Uhr
Dies funktioniert, wenn Sie den ersten Index auf 1 ändern, Sie sollten lernen, zu debuggen, bevor Sie kommentieren … traceback.extract_stack (None, 2)[1][2]
– Jcc. Sanabria
19. Dezember 2018 um 18:35 Uhr
lfurini
import inspect
def foo():
print(inspect.stack()[0][3])
wo
stack()[0]
ist der Anrufer
stack()[3]
ist der Stringname der Methode
Ich hatte “
– Emmagras
18. Oktober 2014 um 14:49 Uhr
für mich funktioniert das nicht, aber das funktioniert: traceback.extract_stack()[-1][2]
– mike01010
22. November 2014 um 3:54 Uhr
Dies funktioniert, wenn Sie den ersten Index auf 1 ändern, Sie sollten lernen, zu debuggen, bevor Sie kommentieren … traceback.extract_stack (None, 2)[1][2]
– Jcc. Sanabria
19. Dezember 2018 um 18:35 Uhr
radato
Ich verwende gerne einen Funktions-Decorator. Ich habe eine Klasse hinzugefügt, die auch mal die Funktion time. Angenommen, gLog ist ein Standard-Python-Logger:
class EnterExitLog():
def __init__(self, funcName):
self.funcName = funcName
def __enter__(self):
gLog.debug('Started: %s' % self.funcName)
self.init_time = datetime.datetime.now()
return self
def __exit__(self, type, value, tb):
gLog.debug('Finished: %s in: %s seconds' % (self.funcName, datetime.datetime.now() - self.init_time))
def func_timer_decorator(func):
def func_wrapper(*args, **kwargs):
with EnterExitLog(func.__name__):
return func(*args, **kwargs)
return func_wrapper
Jetzt müssen Sie Ihre Funktion nur noch dekorieren und voila
@func_timer_decorator
def my_func():