In diesem Thread wird erläutert, wie Sie den Namen einer Funktion als Zeichenfolge in Python abrufen: So erhalten Sie einen Funktionsnamen als Zeichenfolge.
Wie kann ich dasselbe für eine Variable tun? Im Gegensatz zu Funktionen haben Python-Variablen das __name__
Attribut nicht.
Mit anderen Worten, wenn ich eine Variable habe wie:
foo = dict()
foo['bar'] = 2
Ich suche nach einer Funktion / einem Attribut, z. B. retrieve_name()
um aus dieser Liste einen DataFrame in Pandas zu erstellen , wobei die Spaltennamen durch die Namen der tatsächlichen Wörterbücher angegeben werden:
# List of dictionaries for my DataFrame
list_of_dicts = [n_jobs, users, queues, priorities]
columns = [retrieve_name(d) for d in list_of_dicts]
pip3 install python-varname==0.1.5
; importiert mitfrom varname import nameof
Die einzigen Objekte in Python, die kanonische Namen haben, sind Module, Funktionen und Klassen, und natürlich gibt es keine Garantie dafür, dass dieser kanonische Name in einem Namespace eine Bedeutung hat, nachdem die Funktion oder Klasse definiert oder das Modul importiert wurde. Diese Namen können auch nach dem Erstellen der Objekte geändert werden, sodass sie möglicherweise nicht immer besonders vertrauenswürdig sind.
Was Sie tun möchten, ist nicht möglich, ohne rekursiv über den Baum benannter Objekte zu gehen . Ein Name ist eine Einwegreferenz auf ein Objekt. Ein allgemeines Python-Objekt oder ein Python-Objekt mit Gartenvielfalt enthält keine Verweise auf seine Namen. Stellen Sie sich vor, jede ganze Zahl, jedes Diktat, jede Liste, jeder Boolesche Wert müsste eine Liste von Zeichenfolgen führen, die Namen darstellen, die darauf verweisen! Es wäre ein Implementierungs-Albtraum, der für den Programmierer wenig von Vorteil ist.
quelle
__name__
dies immer geändert werden kann, was bedeutet, dass der "kanonische" Name möglicherweise kein Name ist, der zum Abrufen des Objekts verwendet werden kann (z. B. beim dynamischen Erstellen von Klassen).Auch wenn Variablenwerte nicht auf den Namen verweisen, haben Sie Zugriff auf die Liste aller zugewiesenen Variablen und deren Wert. Ich bin daher erstaunt, dass nur eine Person vorgeschlagen hat, sich dort durchzuschleifen, um nach Ihrem Variablennamen zu suchen.
Jemand hat in dieser Antwort erwähnt, dass Sie möglicherweise den Stapel durchlaufen und alle Einheimischen und Globalen überprüfen müssen, um sie zu finden
foo
. Wennfoo
sie jedoch in dem Bereich zugewiesen sind, in dem Sie dieseretrieve_name
Funktion aufrufen , können Sie mitinspect
'scurrent frame
alle diese lokalen Variablen abrufen .Meine Erklärung mag etwas zu wortreich sein (vielleicht hätte ich ein "foo" weniger Wörter verwenden sollen), aber so würde es im Code aussehen ( Beachten Sie, dass Sie es tun werden, wenn mehr als eine Variable demselben Wert zugewiesen ist beide Variablennamen abrufen ):
Wenn Sie diese Funktion von einer anderen Funktion aus aufrufen, können Sie Folgendes tun:
Und Sie möchten das
baz
stattbar
, Sie müssen nur einen Bereich weiter zurückgehen. Dies kann durch Hinzufügen eines zusätzlichen.f_back
in dercaller_local_vars
Initialisierung erfolgen.Sehen Sie hier ein Beispiel: ideone
quelle
import hooks
,ironpython
undjython
a, b = 2, 2
,retrieve_name(a)
undretrieve_name(b)
werden beide Rückkehr['a', 'b']
oder['b', 'a']
true
zu einemis
Vergleich zurückkehrendef foo(bar): retrieve_name(bar)
wird immer bar zurück, aber was ist, wenn Sie wollen ,foo(baz)
um Rückkehrbaz
) stattbar
?callers_local_vars
, um einen Bereich weiter zurück zu gehen, damit der Bereich des Aufrufs angezeigt wirdfoo
. Ändern Sie die Zeile ininspect.currentframe().f_back.f_back.f_locals.items()
(beachten Sie das Extraf_back
).Mit Python 3.8 kann man einfach die F-String-Debugging-Funktion verwenden:
quelle
f'{foo=}'.split('=')[0].split('.')[-1]
Unter python3 erhält diese Funktion den äußersten Namen im Stapel:
Es ist überall im Code nützlich. Durchläuft den umgekehrten Stapel und sucht nach dem ersten Match.
quelle
retrieve_name(SomeClass.some_attribute)
, funktioniert es nicht. Können Sie uns dabei weiterhelfen?stop_on_error
Ich glaube nicht, dass das möglich ist. Betrachten Sie das folgende Beispiel:
Das
a
und zeigtb
auf dasselbe Objekt, aber das Objekt kann nicht wissen, welche Variablen darauf zeigen.quelle
Es wird so verwendet:
quelle
name(variable=variable)
wird ausgegeben['variable']
und usingname(variable=another_variable)
wird nicht ausgegeben['another_variable']
, sondern['variable']
.>>> a = []
>>> b = a
>>> name(a=b)
['a']
>>> name(b=a)
['b']
`Hier ist ein Ansatz. Ich würde dies für nichts Wichtiges empfehlen, da es ziemlich spröde sein wird. Aber es kann getan werden.
Erstellen Sie eine Funktion, die das
inspect
Modul verwendet, um den Quellcode zu finden, der es aufgerufen hat. Anschließend können Sie den Quellcode analysieren, um die Variablennamen zu identifizieren, die Sie abrufen möchten. Hier ist beispielsweise eine aufgerufene Funktionautodict
, die eine Liste von Variablen verwendet und ein Wörterbuch zurückgibt, das Variablennamen ihren Werten zuordnet. Z.B:Würde geben:
Das Überprüfen des Quellcodes selbst ist besser als das Durchsuchen des
locals()
oderglobals()
weil der letztere Ansatz Ihnen nicht sagt, welche der Variablen die gewünschten sind.Hier ist auf jeden Fall der Code:
Die Aktion erfolgt in der Zeile mit
inspect.getouterframes
, die die Zeichenfolge innerhalb des aufgerufenen Codes zurückgibtautodict
.Der offensichtliche Nachteil dieser Art von Magie besteht darin, dass Annahmen darüber getroffen werden, wie der Quellcode strukturiert ist. Und natürlich funktioniert es überhaupt nicht, wenn es im Interpreter ausgeführt wird.
quelle
Ich habe das Paket Zauberei geschrieben , um diese Art von Magie robust zu machen. Du kannst schreiben:
und übergeben Sie das an den Datenrahmenkonstruktor. Es ist äquivalent zu:
quelle
Wenn Sie Ihre eigene Funktion schreiben möchten, können Sie dies so tun, dass Sie nach einer in Einheimischen definierten Variablen suchen und dann die globalen Werte überprüfen. Wenn nichts gefunden wird, können Sie mit id () vergleichen, um festzustellen, ob die Variable auf dieselbe Position im Speicher verweist.
Wenn sich Ihre Variable in einer Klasse befindet, können Sie className verwenden. dict .keys () oder Vars (Selbst-) zu sehen , ob Ihre Variable definiert wurde.
quelle
locals
undglobals
... und Sie riskieren, den Namen falsch zu verstehen, wenn keiner tatsächlich existiert. Es ist eine Menge Arbeit ohne wirklichen nützlichen Gewinn.In Python, die
def
undclass
binden Schlüsselwörter einen bestimmten Namen für das Objekt sie (Funktion oder Klasse) definieren. In ähnlicher Weise erhalten Module einen Namen, weil sie im Dateisystem als etwas Bestimmtes bezeichnet werden. In allen drei Fällen gibt es eine offensichtliche Möglichkeit, dem betreffenden Objekt einen "kanonischen" Namen zuzuweisen.Für andere Arten von Objekten kann ein solcher kanonischer Name jedoch einfach nicht existieren . Betrachten Sie beispielsweise die Elemente einer Liste. Die Elemente in der Liste sind nicht einzeln benannt, und es ist durchaus möglich, dass Sie in einem Programm nur auf Listenindizes in der enthaltenen Liste verweisen können. Wenn eine solche Liste von Objekten an Ihre Funktion übergeben wurde, konnten Sie den Werten möglicherweise keine aussagekräftigen Bezeichner zuweisen.
Python speichert den Namen auf der linken Seite einer Zuweisung nicht im zugewiesenen Objekt, weil:
So haben beispielsweise Funktionen, die mit definiert wurden,
lambda
immer den "Namen"<lambda>
und nicht einen bestimmten Funktionsnamen.Der beste Ansatz wäre einfach, den Anrufer zu bitten, eine (optionale) Liste von Namen einzugeben. Wenn die Eingabe von
'...','...'
zu umständlich ist, können Sie beispielsweise eine einzelne Zeichenfolge akzeptieren, die eine durch Kommas getrennte Liste von Namen enthält (wie dies auch dernamedtuple
Fall ist).quelle
local () - Gibt ein Wörterbuch zurück, das die lokalen Variablen des aktuellen Bereichs enthält. Durch Durchlaufen dieses Wörterbuchs können wir den Schlüssel überprüfen, dessen Wert der definierten Variablen entspricht. Wenn Sie nur den Schlüssel extrahieren, erhalten Sie den Text der Variablen im Zeichenfolgenformat.
von (nach ein wenig Änderungen) https://www.tutorialspoint.com/How-to-get-a-variable-name-as-a-string-in-Python
quelle
Ich denke, es ist so schwierig, dies in Python zu tun, weil Sie den Namen der Variablen, die Sie verwenden, nie kennen. In seinem Beispiel könnten Sie also Folgendes tun:
Anstatt:
quelle
Nur eine andere Möglichkeit, dies basierend auf dem Inhalt der Eingabevariablen zu tun:
(Es gibt den Namen der ersten Variablen zurück, die mit der Eingabevariablen übereinstimmt, andernfalls keine. Sie können ihn ändern, um alle Variablennamen zu erhalten, die denselben Inhalt wie die Eingabevariable haben.)
quelle
Diese Funktion druckt den Variablennamen mit seinem Wert:
quelle
Ich habe eine Methode, und obwohl sie nicht die effizienteste ist ... funktioniert sie! (und es beinhaltet keine ausgefallenen Module).
Grundsätzlich wird die ID Ihrer Variablen mit den IDs von globals () -Variablen verglichen und anschließend der Name der Übereinstimmung zurückgegeben.
quelle
Wenn Sie Ihre Variablen im Auge behalten möchten, können Sie eine einfache Funktion schreiben, die die Variable beschriftet und ihren Wert und Typ zurückgibt. Angenommen, i_f = 3.01 und Sie runden es auf eine Ganzzahl namens i_n, um es in einem Code zu verwenden, und benötigen dann eine Zeichenfolge i_s, die in einen Bericht aufgenommen wird.
Dies wird bei jedem Aufruf zu Debugging-Zwecken im Fenster gedruckt und liefert auch eine Zeichenfolge für den schriftlichen Bericht. Der einzige Nachteil ist, dass Sie die Variable bei jedem Aufruf der Funktion zweimal eingeben müssen.
Ich bin ein Python-Neuling und fand diese sehr nützliche Möglichkeit, meine Bemühungen zu protokollieren, während ich programmiere und versuche, mit allen Objekten in Python umzugehen. Ein Fehler ist, dass whatis () fehlschlägt, wenn es eine Funktion aufruft, die außerhalb der Prozedur beschrieben wird, in der es verwendet wird. Zum Beispiel war int (i_f) nur deshalb ein gültiger Funktionsaufruf, weil die int- Funktion Python bekannt ist. Sie können whatis () mit int (i_f ** 2) aufrufen, aber wenn Sie aus irgendeinem seltsamen Grund eine Funktion namens int_squared definieren, muss diese in der Prozedur deklariert werden, in der whatis () verwendet wird.
quelle
Vielleicht könnte dies nützlich sein:
Die Funktion durchsucht die Liste der IDs von Werten aus dem globalen Bereich (der Namespace könnte bearbeitet werden), ermittelt den Index der gewünschten / erforderlichen Variablen oder Funktion anhand ihrer ID und gibt dann den Namen aus der Liste der globalen Namen zurück auf dem erworbenen Index.
quelle
Die folgende Methode gibt nicht den Namen der Variablen zurück. Mit dieser Methode können Sie jedoch problemlos einen Datenrahmen erstellen, wenn die Variable im globalen Bereich verfügbar ist.
quelle
Für Konstanten können Sie eine Aufzählung verwenden, die das Abrufen des Namens unterstützt.
quelle
Ich versuche, einen Namen von Inspect-Einheimischen zu erhalten, aber es kann var wie a [1], b.val nicht verarbeiten. Danach kam mir eine neue Idee - hol den Variablennamen aus dem Code und versuche es erfolgreich! Code wie unten:
quelle
Sie können Folgendes versuchen, um den Namen einer von Ihnen definierten Funktion abzurufen (funktioniert jedoch nicht für integrierte Funktionen):
quelle