exec() im lokalen Kontext

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
Benutzeravatar
Imaginärteil
User
Beiträge: 12
Registriert: Sonntag 7. Februar 2016, 18:57

Ich benötige in einer meiner Arbeiten exec(), um eins als String gespeicherte Liste in ein Programm einfach einlesen zu können.
Bin wegen folgendem Problem noch auf der Suche nach einer vernünftigen Alternative:

In der Dokumentation von exec() (so sagt es jedenfalls IDLE) wird der lokale Kontext berücksichtigt.
Entweder habe ich das komplett falsch verstanden, falsch geschrieben oder er macht es falsch:

Code: Alles auswählen

def f():
    x = 0
    exec("x = 1")
    return x
Nun, das führt von einer Ausgabe von 0, nicht von einer 1, deren Auswurf für mich eigentlich erwartbarer wäre.
Ich habe ein bisschen rumgesucht, was das angeht, bin aber nicht so schlau draus geworden ...

Bisher hat bei mir exec nur in globalem Kontext funktioniert.
Beispiel:

Code: Alles auswählen

x = 0
exec("x = 1")
print(x)
Führt zu 1. Keine Überraschung, das sollte es auch tun. Steht ja auch nicht in einer Funktion.

Trotzdem funktioniert auch folgendes nicht wie erwartet:

Code: Alles auswählen

x = 2
def f():
    global x
    exec("x = 1")
    return x
Was ich daraus schlussfolgere, ist, dass das Schreiben von exec in definierten Funktionen keinen Sinn macht, weil es nicht das tut, was die "File Scope" dort machen würde.

Sollte es an der Indentation liegen, weiß ich bei Himmel nicht, wie ich die im in exec() einzugebenden String verwirklichen soll.

Belehrt mich eines Besseren! :D
Siehe x²=-1. Durch mich ist der Punkt nicht auf einem Strahl, sondern auf einer Ebene. Bewacht von Euler. Bin mit seinem Werk verwandt. Seine Identität befasst sich mit mir. Durch mich ist jetzt so einiges möglich. Hurra!
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

@Imaginärteil: warum hast Du eine als String gespeicherte Liste? Da ist schon der Fehler. Nimm ein passendes Format, um Listen zu speichern, z.B. JSON.
DasIch
User
Beiträge: 2718
Registriert: Montag 19. Mai 2008, 04:21
Wohnort: Berlin

Imaginärteil hat geschrieben:Ich benötige in einer meiner Arbeiten exec(), um eins als String gespeicherte Liste in ein Programm einfach einlesen zu können.
Nein brauchst du nicht. Es gibt wesentlich bessere Möglichkeiten Strings zu parsen und wesentlich bessere Möglichkeiten Listen zu serialisieren. Am besten du vergisst dass exec existiert und bei der Gelegenheit vergiss global gleich mit.

Die Dokumentation hat übrigens folgendes zu sagen:
exec() hat geschrieben:Note: The default locals act as described for function locals() below: modifications to the default locals dictionary should not be attempted. Pass an explicit locals dictionary if you need to see effects of the code on locals after function exec() returns.
locals() hat geschrieben:Note: The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
Der Code tut also genau dass was man erwarten würde. exec() führt Code zwar im selben Scope aus aber in einem eigenen Frame wie bei einem Funktionsaufruf, was nicht weniger überraschend ist weil exec() selbst eine Funktion ist.
Antworten