eval() ?!

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.
Ravebaby
User
Beiträge: 14
Registriert: Donnerstag 24. Februar 2005, 10:32
Kontaktdaten:

Donnerstag 24. Februar 2005, 10:51

Zu was ist denn bitteschön dieses eval() sinnvoll?!
Ich hab 2 Bücher daheim und mir x online Links angeschaut. Aber überall steht nich viel mehr als ein Satz dazu.

Soviel weiß ich bisher:
"eval wertet einen String aus, der ein Ausdruck sein muss. Damit können dynamisch erzeugte Anweisungen ausgeführt werden."
Was soll das heißen?
Das man mittels eval() einen String zu einer Liste konvertieren kann, hab ich schon verstanden. Aber sonst?

Irgendwo stand auch mal:
"Damit ist der Interpreter Bestandteil der Programmiersprache. Damit kann man im laufenden Programm Quelltext erzeugen und ausführen lassen."
Wie das?

Und es soll sicherheitstechnisch nicht ganz ungefährlich sein, weil es beliebigen Code ausführen kann.
Warum benutzt man es denn dann?

Und was bedeutet das:
"ohne eval wuerde es nur den namen der variablen, nicht deren inhalt ausgeben."

Weiß jemand mehr dazu?
Würde mir sehr weiterhelfen!!!
Danke!!
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Donnerstag 24. Februar 2005, 11:36

Hi. Eval ist deswegen ein Teil des Interpreters, weil man eine String übergibt und dieser wie eine normale Anweisung ausgeführt wird, man kann also Python sagen: "Interpretiere mal schnell das hier und sag mir das Ergebniss, als würde es schon im Quelltext stehen"

Code: Alles auswählen

>>> x=1
>>> y=eval("x+1")
>>> y
2
>>> def f(x):
	return x**2

>>> print eval("f(y)")
4
>>> help(eval)
Help on built-in function eval in module __builtin__:

eval(...)
    eval(source[, globals[, locals]]) -> value
    
    Evaluate the source in the context of globals and locals.
    The source may be a string representing a Python expression
    or a code object as returned by compile().
    The globals must be a dictionary and locals can be any mappping,
    defaulting to the current globals and locals.
    If only globals is given, locals defaults to it.
Tja, und daraus sollte man erkennen können, das es möglich ist beliebige Strings zu übergeben. Diese Strings können z.T. während der Laufzeit erzeugt wurden sein und deswegen beliebigen (gültigen!!!) Code enthalten. Es gibt nur eine Einschränkung: es dürfen nur expressions übergeben werden und keine statements, Zuweisungen und Schleifen sind also nicht möglich. Dies ist mit exec möglich. Wozu es nützlich ist hab ich bis heute noch nicht entdeckt, da ich immer wieder andere Methoden gefunden habe, aber es ist gut zu wissen das es sowas gibt :wink:
Gast

Donnerstag 24. Februar 2005, 12:06

hi,....

ich habe es verwendet um die eingabe in einer gui umzuwandeln. ich lege oft verschiedene typen mit pickle in einer textdatei ab,

Code: Alles auswählen

entry.get()
liefert einen string, um das ganze dann zu dem zu machen was ich wirklich brauche, habe ich eval benützt:

Code: Alles auswählen

>>> l="[2,3,5]"
>>> eval(l)
[2, 3, 5]
>>> 
wurde auch hier besprochen:


http://python.sandtner.org/viewtopic.php?t=2717



mfg

rolgal
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Donnerstag 24. Februar 2005, 12:10

Hi!

Und genau das ist dann eine Sicherheitslücke. Was, wenn jemand in das Entry rm -rf oder ähnliches einträgt?

Gruß, mawe
Gast

Donnerstag 24. Februar 2005, 12:15

hi mawe!

stimmt, aber nachdem nur ich das programm verwende, habe ich mir bez. sicherheitslücken keine gedanken gemacht.

gibts ne andere möglichkeit?

mfg

rolgal
Gast

Donnerstag 24. Februar 2005, 12:26

hm, am besten wäre wohl falsche einträge abzufangen, also nur jene zulassen die ein [,{ oder ( aufweisen, oder?

mfg


rolgal
Milan
User
Beiträge: 1078
Registriert: Mittwoch 16. Oktober 2002, 20:52

Donnerstag 24. Februar 2005, 12:37

Nö. Am besten wäre es einen Parser zu schreiben der ohne eval arbeitet, denn bei dir geht sowas hier trotzdem:

Code: Alles auswählen

>>> eval("[sys.exit(1)]")

Traceback (most recent call last):
  File "<pyshell#1>", line 1, in -toplevel-
    eval("[sys.exit(1)]")
  File "<string>", line 0, in -toplevel-
SystemExit: 1
Man kann natürlich auch os.system(...) schreiben, das wäre dann fatal. Deswegen benutze ich es auch nicht, da os in den allermeisten Fällen importiert ist...
CM
User
Beiträge: 2464
Registriert: Sonntag 29. August 2004, 19:47
Kontaktdaten:

Donnerstag 24. Februar 2005, 13:06

<off topic>
Hi rolgal,

fürs pickling brauchst Du kein "eval". Es geht auch so:

Code: Alles auswählen

pickle.dump(data,open(path,'w'),protocol)
#und zurück mit
data = pickle.load(open(path))
Hierbei kann "data" alles Mögliche sein - auch eine liste. Das shelve-Modul verwendet ebenfalls pickle und auch da braucht es kein eval, um an die abgelegten Daten zu kommen.
Dann hast Du auch keine Sicherheitslücke, weil kein Ausdruck Deiner Daten an sich ausgeführt wird.

Gruß,
Christian
</off topic>
edit:
P.S. Oder Du nutzt, bei den Daten eines GUI geht das möglicherweise, das Snippet, daß ich heute morgen gepostet hatte ... Deine Daten können dabei auch ohne eval beliebig komplex sein.
Zuletzt geändert von CM am Donnerstag 24. Februar 2005, 13:25, insgesamt 2-mal geändert.
Gast

Donnerstag 24. Februar 2005, 13:22

hi,...

danke für die antworten, guck mir das gleich mal in ruhe an!

mfg

rolgal
Ravebaby
User
Beiträge: 14
Registriert: Donnerstag 24. Februar 2005, 10:32
Kontaktdaten:

Donnerstag 24. Februar 2005, 15:17

auch von mit ein fettes Dankeschön. Endlich kann ich mit dem eval() was anfangen *freu* :wink:
Gast

Donnerstag 24. Februar 2005, 16:03

hi christian,....

habe mir auch dein snippet, interessantes beispiel, mir ist da etwas nicht klar:

Code: Alles auswählen

pickle.dump(self,open(fname,'w'),2)
entspricht dem hier, was du zuerst für mich gepostet hast:

Code: Alles auswählen

pickle.dump(data,open(path,'w'),protocol) 
was hat es mit dem protocol, also der 2 auf sich?

mfg

rolgal
Gast

Donnerstag 24. Februar 2005, 16:06

hi christian,...

irgendwas funzt nicht, ich habe mal die 2 einfach übernommen:

Code: Alles auswählen

>>> data="[1,2,3]"
>>> import pickle

>>> pickle.dump(data,open('/home/rolgal/testpickle.txt','w',2))
>>> data = pickle.load(open('/home/rolgal/testpickle.txt'))
>>> data
'[1,2,3]'

aber da habe ich eben wieder einen string und keine liste :?:

mfg

rolgal
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Donnerstag 24. Februar 2005, 16:17

Hi rolgal!

Wenn die Listen die Du eingibst immer flach sind (und mit , getrennt), kannst Du das versuchen:

Code: Alles auswählen

l = "[1,2,3]"
x = l.strip('"[]').split(',')
print x
Nich wirklich geistreich und sehr unflexibel, ich weiß, aber vielleicht kannst Du's brauchen :wink:

Gruß, mawe
Gast

Donnerstag 24. Februar 2005, 16:37

hi mawe,...

danke mal für die anregung. aber ich gebe die unterschiedlichsten typen ein, was ist genau eine liste die nicht flach ist? wenn verschiedene typen in ihr enthalten sind? also z.b.

Code: Alles auswählen

l=[1,2,'text']
:?:

mfg
rolgal
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Donnerstag 24. Februar 2005, 16:47

Hi rolgal!

Mit flach hab ich gemeint, nicht so

Code: Alles auswählen

[[1,2],[3,4]]
also nicht verschachtelt. Heisst das überhaupt so? Ich weiß nicht mal ob das andere flach heisst, wollte nur intelligent klingen :D

Gruß, mawe
Antworten