Python-Statement in String

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.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Das Stichwort heißt eval().

Ist aber meistens keine gute Idee.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

Liegt nichtmal an Syntaxfehlern, die kannst du sogar Abfangen.
Hier steht einiges
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

``print`` ist ein Statement. Du kannst entweder statt ``print`` ``sys.stdout.write()`` nutzen oder statt ``eval()`` ``exec``. Jedoch ist auch ``exec`` keine gute Idee.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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??!
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

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()')
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Karl
User
Beiträge: 252
Registriert: Freitag 29. Juni 2007, 17:49

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.
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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.
TUFKAB – the user formerly known as blackbird
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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?
Benutzeravatar
keppla
User
Beiträge: 483
Registriert: Montag 31. Oktober 2005, 00:12

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.
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

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.
TUFKAB – the user formerly known as blackbird
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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.
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
da.dom
User
Beiträge: 114
Registriert: Dienstag 10. Juni 2008, 14:42

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
Antworten