Seite 1 von 3

Python-Statement in String

Verfasst: Donnerstag 12. Juni 2008, 13:28
von da.dom
HuHu...

eine frage:

kann ich ein Python Statement, das in einem String gespeichert ist zur Ausführung bringen?

Code: Alles auswählen

pythonStatement='print "Hallo ich bin ein Statement"'
das z.B. möchte ich nicht als String wieder ausgeben, sonder ich will das enthaltene Statement interpretieren lassen...geht so was?

Danke schon mal
D

Verfasst: Donnerstag 12. Juni 2008, 13:43
von numerix
Das Stichwort heißt eval().

Ist aber meistens keine gute Idee.

Verfasst: Donnerstag 12. Juni 2008, 14:13
von da.dom
supi, dank dir, für die Bildung: warum keine gute Idee? Wegen Syntax fehlern bei der Laufzeit?

PS: das zum Thema Fehler :)

Code: Alles auswählen

eval('print "hallo"')

>>
    eval('print "hallo"')
  File "<string>", line 1
    print "hallo"
        ^
SyntaxError: invalid syntax

Verfasst: Donnerstag 12. Juni 2008, 14:22
von Karl
Liegt nichtmal an Syntaxfehlern, die kannst du sogar Abfangen.
Hier steht einiges

Verfasst: Donnerstag 12. Juni 2008, 14:41
von da.dom
mhh ich glaube ich scheine nicht Klug genug zu sein :)

print eval('1+1')

= funktioniert

eval('print "hallo"')

= invalis Syntax

fehlt ihm da das Dictionary, oder hab ich die API da falsch verstanden ? "print" gehört doch zum "Standard" Dictionary oder etwa nicht (bin mit meiner Lektüre über Python noch nicht bei Dictionaries angekommen)

Danke mal wieder
D

Verfasst: Donnerstag 12. Juni 2008, 14:45
von Leonidas
``print`` ist ein Statement. Du kannst entweder statt ``print`` ``sys.stdout.write()`` nutzen oder statt ``eval()`` ``exec``. Jedoch ist auch ``exec`` keine gute Idee.

Verfasst: Donnerstag 12. Juni 2008, 15:14
von da.dom
eval('sys.stdout.write("hallo")')

funktioniert :) danke. Die Frage bleibt offen: warum keine gute Idee, wenn es nicht an der Syntax liegt? Hab im dem Thread was von Sicherheit gelesen??!

Verfasst: Donnerstag 12. Juni 2008, 15:20
von Karl
da.dom hat geschrieben:eval('sys.stdout.write("hallo")')

funktioniert :) danke. Die Frage bleibt offen: warum keine gute Idee, wenn es nicht an der Syntax liegt? Hab im dem Thread was von Sicherheit gelesen??!
Wie gesagt, ein SyntaxError ist nicht das Problem. Diesen kannst du ohne Probleme abfangen:

Code: Alles auswählen

try:
	eval(raw_input())
except SyntaxError:
	print "SyntaxError!"
Aber ja, in dem Thread geht es darum, dass es unsicher ist.
Und die Lösung, die in dem Thread genannt wird ist, einen eigenen Parser zu baun.

Verfasst: Donnerstag 12. Juni 2008, 15:33
von Leonidas
da.dom hat geschrieben:Hab im dem Thread was von Sicherheit gelesen??!
Nicht nur das, es ist unsicher und der Code der ``eval`` nutzt wird sehr schnell unübersichtlich, weil man damit dynamisch Code konstruieren und ausführen kann - das will ich nicht debuggen müsen. Zudem noch die meisten ``eval`` dazu benutzen numerierte Variablen anzulegen, was man sich durch Listen und Dictionaries sparen kann.

Verfasst: Donnerstag 12. Juni 2008, 15:39
von Rebecca
Wenn man eval benuzt, um Code von User-Eingaben entgegenzunehmen, sollte man beruecksichtigen, dass der User damit sehr viele Kommandos ausfuehren und sogar den eigentlichen Programmcode beeinflussen kann:

Code: Alles auswählen

eval('os.remove("wichtig.txt")')

Code: Alles auswählen

eval('wichtiges_objekt.wichtige_funktion()')

Verfasst: Donnerstag 12. Juni 2008, 16:54
von birkenfeld
Karl hat geschrieben:
da.dom hat geschrieben:eval('sys.stdout.write("hallo")')

funktioniert :) danke. Die Frage bleibt offen: warum keine gute Idee, wenn es nicht an der Syntax liegt? Hab im dem Thread was von Sicherheit gelesen??!
Wie gesagt, ein SyntaxError ist nicht das Problem. Diesen kannst du ohne Probleme abfangen
Argh. eval() ist hier einfach nicht das richtige Werkzeug. Die Fehler, die daraus resultieren, abzufangen, bringt doch überhaupt nichts.

Verfasst: Donnerstag 12. Juni 2008, 17:11
von Karl
birkenfeld hat geschrieben:
Karl hat geschrieben:
da.dom hat geschrieben:eval('sys.stdout.write("hallo")')

funktioniert :) danke. Die Frage bleibt offen: warum keine gute Idee, wenn es nicht an der Syntax liegt? Hab im dem Thread was von Sicherheit gelesen??!
Wie gesagt, ein SyntaxError ist nicht das Problem. Diesen kannst du ohne Probleme abfangen
Argh. eval() ist hier einfach nicht das richtige Werkzeug. Die Fehler, die daraus resultieren, abzufangen, bringt doch überhaupt nichts.
Hab ich das etwa behauptet? Ich wollte damit nur deutlich machen, dass es nicht darum geht, dass eval() Syntaxerror erzeugen kann, sondern die anderen Dinge, die hier erwähnt wurden. Dass eval() nicht das richtige Werkzeug ist, ist mir klar, darum hab ich auch auf die Alternative in diesem Thread verwiesen.

Verfasst: Freitag 13. Juni 2008, 09:03
von da.dom
HiHi..

werde mir den Beitrag im verlinkten Thread noch mal genau durchlesen, für mein kleines Beispiel reicht eval() trotzde Sicherheitsbedenken. (kurz wofür: ich lerne gerade Python und habe mir anegwöhnt, bei neuen Sachen, mir selber eine (sehr) einfache HTML Zusammenfassung zu schreiben. Bei Python habe ich meine ganzen Übungen, in einer "Spagetti-Code Datei hinterheinander weg geschrieben und mit ausfürlichen Kommentaren versehen. Als meine erste "richtige" (nicht lachen :) ) Aufgabe habe ich mir dann ein kleines Script geschrieben, das mir meine Lern-Python-Datei in eine (sehr) einfach formatierte HTML Datei konvertiert. Damit habe ich dann allerdings nur die Kommentare und die Statements mit drin, aber nicht die direkte Ausgabe der Statements (falls ich sie nicht selber schreiben), so in etwa sieht das zur Zeit aus:

Code: Alles auswählen

"""Strings 
- Folge von Zeichen = ein sequenzieller Datentyp
"""
print "Hallo" " Du"     #aufeinander Folgende Strings werden zusammengezogen
wird bei jedem ausführen der Datei durch meinen parser Gejagt und spuckt mir eine HTML datei aus ~ so:

Strings
- Folge von Zeichen = ein sequenzieller Datentyp


print "Hallo" " Du" #aufeinander Folgende Strings werden zusammengezogen


an der Stelle will ich automatisch mein geschriebenes Kommentar mit der Python-Ausgabe erweitern..

kurze Frage noch:

Warum ist "print" kein 'echtes'(?) Statement was ich mit eval ausführen kann?

Danke
D

Verfasst: Freitag 13. Juni 2008, 09:43
von mitsuhiko
da.dom hat geschrieben:Warum ist "print" kein 'echtes'(?) Statement was ich mit eval ausführen kann?
Print *ist* ein Statement, aber keine Expression. Das gilt auch für def, class, import, from, with etc.

Verfasst: Freitag 13. Juni 2008, 09:55
von da.dom
mitsuhiko hat geschrieben:
da.dom hat geschrieben:Warum ist "print" kein 'echtes'(?) Statement was ich mit eval ausführen kann?
Print *ist* ein Statement, aber keine Expression. Das gilt auch für def, class, import, from, with etc.
uff und der Unterschied liegt wo?

Verfasst: Freitag 13. Juni 2008, 10:32
von keppla
da.dom hat geschrieben:uff und der Unterschied liegt wo?
Praktisch gesagt, alles was auf der rechten seine einer Zuweisung stehen kann, ist eine expression.
Ausnahme/Mehrdeutigkeit ist das if, als if,elif,else ists ein Statement, als = a if b else c eine expression.

Verfasst: Freitag 13. Juni 2008, 10:33
von mitsuhiko
da.dom hat geschrieben:uff und der Unterschied liegt wo?
Expressions geben was zurück. Und wenn es nur None ist. 1 + 1 gibt zb 2 zurück. int("42") gibt einen integer zurück, dict.update() verändert ein dict und gibt zumindest None zurück.

print kann nix zurückgeben, das ist ein Statement. wenn du "foo = print 42" machst bekommst du einen SyntaxError.

Verfasst: Freitag 13. Juni 2008, 10:34
von Leonidas
da.dom hat geschrieben:uff und der Unterschied liegt wo?
Dass die Statements Keywords sind und du keine Objekte an ``print`` etc. binden kannst. Noch dazu haben Statements keinen Rückgabewert. Also Programmieranfänger ist der Unterschied zwischen Statement und Expression nicht besonders relevant, auch später ändert es sich nicht sonderlich.

Verfasst: Freitag 13. Juni 2008, 14:12
von birkenfeld
Statements geben keinen Wert zurück und können damit nicht Teil einer Expression sein.

Stell dir ein Python-Modul zusammengesetzt aus Statements vor, die beim Import oder direktem Ausführen eines nach dem anderen ausgeführt werden. Manche Statements, wie def, class, if oder with, enthalten (im Quellcode eingerückte) Blöcke mit Unterstatements, sog. Suiten. Fast alle Statements (außer z.b. pass) enthalten darüberhinaus auch Expressions, die als Teil der Ausführung des Statements ausgewertet werden.

Nicht jedes Statement muss übrigens mit einem Schlüsselwort eingeleitet werden -- eine Zuweisung ist auch ein Statement.

Und damit du auch so etwas problemlos schreiben kannst:

Code: Alles auswählen

def foo():
    "Docstring"
ist auch jede Expression für sich alleine ein gültiges Statement.

Verfasst: Montag 16. Juni 2008, 09:53
von da.dom
HuHu..

erst mal danke für die vielen Antworten, in dem Fall sehe ich jetzt etwas klarer...ein Problem stellt sich bei meinem "komplexer" werdenden Übungen aber:

Code: Alles auswählen

map={1337:"leet",abc:123,123:XXX}
                  
#der Code der als String ausgeführt werden soll:    
print len(map)      
bei meinen Einzeilern was das bisher kein problem, aber wie lasse ich einen String interpretieren, der auf Variablen zugreift die vorher definiert wurden? Vorher ebenfalls durch eval ausführen kann ich ja nicht (map=.... ist ja ein Statement aber keine Expression (richtig :) ?))

Grüße
D