HOWTO · Python
Konvertieren einer Zeichenkette in einen Variablennamen in Python
In diesem Artikel werden verschiedene Möglichkeiten zum Konvertieren eines Zeichenkettenwerts in einen Variablennamen in Python erläutert.
Auf dieser Seite
Python verwendet den Wert eines Strings nicht als Namen auf der linken Seite einer normalen Variablen-Zuweisung. Um einen Namen zur Laufzeit zu erstellen oder darauf zuzugreifen, wählen Sie den Namespace, der ihn enthalten soll: globals() für Variablen auf Modulebene, locals() zum Untersuchen lokaler Namen, exec() für generierten Quellcode, setattr() für Objektattribute oder ein Dictionary, wenn die Namen eigentlich Daten sind.
Hinweis: Dynamische Variablennamen können Abhängigkeiten verbergen, einen Namespace verschmutzen und einen
NameErrorauslösen, wenn Code einen Namen liest, der nie erstellt wurde. Sie sind selten die beste Wahl für Produktionssoftware; verwenden Sie vorzugsweise ein Dictionary, es sei denn, eine echte globale Variable oder ein Objektattribut ist erforderlich.
Einen String mit globals() und locals() in Python in einen Variablennamen umwandeln
Die eingebaute Funktion globals() gibt das Dictionary der aktuellen globalen Symboltabelle zurück. Dieses Dictionary bildet den Namen jeder globalen Variablen auf ihren Wert ab. Auf Modulebene erzeugt das Schreiben eines neuen Schlüssels über dieses Dictionary eine echte globale Variable mit diesem String als Namen.
Führen Sie dieses Beispiel aus:
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
def create_global_variable(name, value):
globals()[name] = value
variable_name = "dynamicGlobalVar"
variable_value = 10
create_global_variable(variable_name, variable_value)
print(dynamicGlobalVar)
10
Die Funktion erhält "dynamicGlobalVar" als Argument name und speichert 10 unter diesem Schlüssel in der globalen Symboltabelle. Der spätere Ausdruck dynamicGlobalVar funktioniert, weil das Modul nun eine globale Variable mit genau diesem Namen besitzt. Der String muss ein gültiger Python-Bezeichner sein, wenn Quellcode ihn namentlich ansprechen soll; andernfalls rufen Sie den Wert über globals()[name] ab.
Ein globaler Name muss erstellt werden, bevor er gelesen wird. Wäre dynamicGlobalVar nicht zuerst in die globale Symboltabelle eingetragen worden, würde die letzte Zeile einen NameError auslösen. Verwenden Sie in echtem Code für das Schreiben vorzugsweise eine Variable wie variable_name, statt einen ungeprüften String im ganzen Programm einzubetten.
Mit locals() auf eine lokale Variable zugreifen
Die Funktion locals() gibt ein Mapping zurück, das die aktuelle lokale Symboltabelle darstellt. Innerhalb einer Funktion ist es nützlich, um einen in einem String gehaltenen lokalen Namen nachzuschlagen:
def demonstrate_locals():
temp_var = "Dynamic Content"
name = "temp_var"
return locals().get(name)
print(demonstrate_locals())
Dynamic Content
Hier löst locals().get(name) "temp_var" auf, während die Funktion läuft, und gibt den Wert der vorhandenen lokalen Variable zurück. Die Verwendung von .get() ist sicherer als ein direkter Indexzugriff auf das Mapping, da es None zurückgibt, wenn der angeforderte Name fehlt.
Verlassen Sie sich nicht darauf, dass locals()[name] = value eine funktionslokale Variable erzeugt. Python-Implementierungen dürfen lokale Variablen optimieren, und Schreibzugriffe auf das zurückgegebene Mapping müssen die echten lokalen Bindungen des Interpreters nicht aktualisieren. Betrachten Sie locals() vor allem als Werkzeug zum Nachschlagen und Untersuchen; verwenden Sie globals(), setattr() oder ein Dictionary, wenn das Programm einen beschreibbaren dynamischen Namen benötigt.
Einen String mit exec() in Python in einen Variablennamen umwandeln
Die Funktion exec() führt Python-Quellcode aus, der als String übergeben wird. Enthält dieser String eine Zuweisung, erzeugt deren Ausführung die entsprechende Variable im aktuellen Ausführungskontext.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
variable_name = "dynamicVar"
value = 42
exec(f"{variable_name} = {value}")
print(dynamicVar)
42
Der f-String baut den Quelltext dynamicVar = 42, und exec() führt diese Zuweisung aus. Auf Modulebene ist das Ergebnis eine neue globale Variable namens dynamicVar. Wenn Sie nicht numerische Werte einfügen, verwenden Sie repr() oder eine gleichwertige Formatierung, damit der generierte Quelltext ein gültiges Python-Literal enthält.
exec() ist mächtig, weil der String mehr als eine einzelne Zuweisung enthalten kann: Er kann Schleifen, Importe, Funktionsdefinitionen oder beliebige Aufrufe ausführen. Diese Mächtigkeit ist auch seine größte Gefahr. Übergeben Sie niemals benutzergesteuerten oder anderweitig nicht vertrauenswürdigen Text an exec(); schon ein bösartiges Namens- oder Wertfragment kann schädlichen Code ausführen. Wie bei locals() kann man sich auch bei exec() nicht darauf verlassen, dass optimierte funktionslokale Variablen aktualisiert werden; diese Technik ist daher auf Modulebene oder mit einem expliziten Namespace-Dictionary am deutlichsten.
Einen String mit setattr() in Python in einen Variablennamen umwandeln
Wenn die gewünschte „Variable“ in Wirklichkeit ein Attribut an einem Objekt, einer Klasse oder einem Modul ist, ist setattr() das direkte Werkzeug. Es nimmt ein Objekt, einen Attributnamen als String und den zuzuweisenden Wert entgegen.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
class Settings:
pass
settings = Settings()
attribute_name = "theme"
attribute_value = "dark"
setattr(settings, attribute_name, attribute_value)
print(settings.theme)
dark
Der Aufruf ist gleichwertig mit settings.theme = "dark", nur dass der Attributname zur Laufzeit aus attribute_name stammt. Das ist nützlich für Konfigurationsobjekte, Datensätze, Plugin-Hooks und andere Stellen, an denen ein Namespace-Objekt bereits Teil des Designs ist.
setattr() erzeugt keine gewöhnliche Modul- oder Funktionsvariable; es aktualisiert den Attribut-Namespace des Zielobjekts. Verwenden Sie getattr(settings, attribute_name), um den Wert dynamisch zu lesen, oder getattr(settings, attribute_name, default_value), wenn ein Rückfallwert benötigt wird.
Ein Dictionary statt dynamischer Variablennamen in Python verwenden
Ein Dictionary ist meist die klarste Antwort, wenn ein Programm Werte unter Namen speichert, die erst zur Laufzeit bekannt sind. Der String bleibt ein Schlüssel, sodass die Sammlung dynamischer Namen explizit und leicht zu prüfen bleibt.
Der Code und die angezeigten Bezeichnungen oder Ausgaben in diesem Abschnitt bleiben auf Englisch.
dynamic_vars = {}
var_name = "temperature"
var_value = 23
dynamic_vars[var_name] = var_value
print(dynamic_vars["temperature"])
23
Dadurch entsteht dieselbe Zuordnung wie bei einer Variablen namens temperature mit dem Wert 23, ohne dass Namen in einen Python-Namespace eingetragen werden. Schlüssel können aufgelistet, an eine andere Funktion übergeben, serialisiert oder entfernt werden, ohne globals() nach unerwarteten Einträgen durchsuchen zu müssen.
Dictionary-Schlüssel unterliegen außerdem nicht den Regeln für Python-Bezeichner, sodass Namen wie "daily total" als Daten verwendet werden können. Greifen Sie mit dynamic_vars[var_name] auf einen erforderlichen Schlüssel zu, oder verwenden Sie dynamic_vars.get(var_name), wenn ein fehlender Schlüssel einen Rückfallwert liefern statt fehlschlagen soll. Dies vermeidet die Behandlung von NameError, da das Programm eine Datenstruktur abfragt, statt Variablen auf Quelltextebene aufzulösen.
Fazit
Python bietet mehrere Möglichkeiten, einen Laufzeit-String in einen nutzbaren Namen zu verwandeln. globals() kann über die globale Symboltabelle eine echte Variable auf Modulebene erzeugen. locals() kann lokale Namen nachschlagen, ist aber als Schreibmechanismus unzuverlässig. exec() kann eine generierte Zuweisung ausführen, birgt jedoch die größten Sicherheits- und Verständlichkeitsrisiken. setattr() ist angebracht, wenn der dynamische Name zu einem Objekt oder Modul gehört.
Für die meisten Programme ist ein Dictionary die sicherste und wartbarste Wahl. Es hält dynamische Namen als Daten, vermeidet das Verschmutzen von Python-Namespaces und macht das Verhalten bei fehlenden Namen explizit. Reservieren Sie echte dynamische Variablen oder Attribute für Designs, die sie tatsächlich benötigen.