Ist 'try' tatsächlich einfach ein Versuch?

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
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

Hallo,

bin gerade über diesen Beitrag gestolpert und fand
pillmuncher hat geschrieben:Easier to Ask Forgiveness than Permission (EAFP), im Gegensatz zu: Look Before You Leap (LBYL).
irgendwie lustig.
Ohne jetzt ein großes Ding daraus machen zu wollen würde mich interessieren, was beim try-statement tatsächlich geschieht:
Führt Python die Anweisung(en) einfach mal aus und schaut, was passiert (so wie ich das immer mach' :roll: ) oder
wird eine Anweisung analysiert und daraufhin entschieden, welche exception diese Anweisung werfen würde oder auch nicht.

Mein erster Gedanke war, dass es wohl so sein wird, dass Python eine Anweisung nach einem try-statement einfach mal ausführt, so wie das ja bei jeder anderen Anweisung auch geschieht. Letztlich spricht man ja auch vom "abfangen" einer exception.....
Ich denke, ich habe mir die Antwort gerade selbst gegeben... :) (Wer schreibt, schaut sich beim Denken zu!)

Ok, das scheint klar zu sein, nur: Die exception(s), die ich über das try-statement abfange, die müssen ja auch irgendwo produziert werden. Mit anderen Worten: Irgendwo muss ja ein

Code: Alles auswählen

'2' + 2
"angeschaut" und entschieden werden: Das geht so nicht, weil...
Wer übernimmt diesen Job? Python selbst oder schickt Python eine Anfrage: "Ich bräuchte mal eben ein Ergebnis von '2' + 2" und erhält dann die Antwort: "Das wird so nicht funktionieren, weil..."

Oder hab' ich eine komplett falsche Vorstellung und die Frage stellt sich deshalb nicht?

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
BlackJack

@mutetella: An wen sollte Python denn eine Anfrage schicken ob etwas geht oder nicht. Also zumindest in dem Beispiel ``'2' + 2`` ist doch nur Python involviert. Nimm doch mal ein etwas allgemeineres Beispiel ``a + b``. Da kann man doch durch drauf schauen gar nicht entscheiden ob das nun geht oder nicht. Es wird ausgeführt. Und wenn dabei einer der Beteiligten feststellt, dass geht nicht, dann wird er ``raise``\n. Entweder in Python-Code oder bei CPython die entsprechenden API-Aufrufe tätigen. Im konkreten ``'2' + 2``-Fall wird der Code in der `__add__()`-Methode von `str`-Objekten feststellen, dass das zweite Argument den falschen Typ hat.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Ja, die Anweisung wird einfach ausgeführt. Das heißt auch, dass bei einer Exception der Zustand deines Programmes inkonsistent sein kann, also musst du dann bei der Fehlerbehandlung gegebenfalls aufräumen.

Bei ``"2" + 2`` wird etwa folgendes gemacht: ``"2".__add__(2)`` ich denke es ist klar dass in ``__add__`` geschaut wird ob man die Operation ausführen kann, ansonsten wird eine Exception geworden. Zumindest sollte man sich das so vorstellen, bei eingebauten Typen kann es da gewisse Optimierungen geben. Bei selbst geschriebenen Python-Objekten ist das jedenfalls so.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

mutetella hat geschrieben:Wer übernimmt diesen Job? Python selbst oder schickt Python eine Anfrage: "Ich bräuchte mal eben ein Ergebnis von '2' + 2" und erhält dann die Antwort: "Das wird so nicht funktionieren, weil..."
Python selbst. Anders hätte Python keine Möglichkeit Ausnahmen auszulösen. Beispiel Array-Zugriff. Würde Python nicht vor dem Zugriff prüfen, ob der Index wirklich gültig ist, würde sich unter Umständen das Betriebsystem dazu entschließen, Python einfach zu töten wenn der Index falsch ist (Segmentation fault), da gibts dann keine Ausnahme mehr, nur noch Crash des Interpreters.
Benutzeravatar
snafu
User
Beiträge: 6908
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ich vermute mal, mutella hat etwas in der Art gedacht, dass theoretisch schon während des Parsens eine bestimmte Folge von Tokens als fehlerhafter Code erkannt werden könnte (hier: Addition von Integer und String) und die Ausnahme möglicherweise schon an dieser Stelle geworfen wird, ohne dass `__add__()` überhaupt angefasst wird. Ich bin jetzt nicht mit dem entsprechenden Code vertraut, kann mir so etwas aber ebenfalls kaum vorstellen.

EDIT: Okay, hat er vielleicht auch nicht so gemeint. Das ist eher die einzige mir eingefallene Möglichkeit, wie man Fehler entdecken kann, ohne Code auszuführen. Unter "Anfrage schicken, um ein Ergebnis zu erhalten" kann ich mir herzlich wenig vorstellen. Und wenn, dann ist die "Anfrage" halt "führe Code xyz aus".

EDIT2: Gut, im Prinzip (ich weiß, dass es nicht so ist) könnte der Code in einem "try-Block" ja isoliert in einer Sandbox ausgeführt werden, die einfach den Namensraum übertragen bekommt, den Code ausführt und nur im Erfolgsfall das Ergebnis übermittelt und andernfalls so tut, als wäre nichts geschehen (außer halt mitzuteilen, dass ein Fehler aufgetreten ist). Das wäre aber erstens an den Stellen problematisch, die nichts mehr mit Python selbst zu tun haben, d.h. wenn es z.B. um das Löschen von Dateien geht (*könnte* man noch simulieren). Selbst wenn, dann wird spätestens die Nutzung von externen Programmen zum Problem, da man dies in seiner Wirkung nicht mehr rückgängig machen kann. Und der zweite Punkt ist die zusätzliche Komplexität, die so etwas wohl ausmachen würde. Sei es das Schreiben von "Simulationscode" (wie gerade schon angesprochen) oder das ständige "Undo-Denken", dass man vermutlich beim Durchgehen des Python-Codes im Hinterkopf haben müsste.
mutetella
User
Beiträge: 1695
Registriert: Donnerstag 5. März 2009, 17:10
Kontaktdaten:

snafu hat geschrieben:Ich vermute mal, mutella hat etwas in der Art gedacht, dass theoretisch schon während des Parsens eine bestimmte Folge von Tokens als fehlerhafter Code erkannt werden könnte (...) ohne dass `__add__()` überhaupt angefasst wird.
Jepp. Genau das war die Frage!
snafu hat geschrieben:Unter "Anfrage schicken, um ein Ergebnis zu erhalten" kann ich mir herzlich wenig vorstellen. Und wenn, dann ist die "Anfrage" halt "führe Code xyz aus".
Nun ja, ich weiß halt nicht, wo z. B. ein 2 + 2 stattfindet.
Letztlich kann Python ja nicht rechnen, das Ergebnis bekommt Python doch irgendwo her, oder?
'2.__add__(2)' respektive 'int(2).__add__(2)' ist doch erstmal nur ein Vorgang, mit dem sich Python selbst ein Verständnis darüber einholt, was denn in einem nächsten Schritt als Anfrage an die Stelle, die letztlich das Ergebnis 4 liefert, formuliert werden soll.

Jedenfalls ist mir nun schon klar, dass die exception von Python geworfen wird, das Beispiel Array-Zugriff von Darii ist da ja recht klar.

Es ist doch so: Solange man über zu wenig Informationen verfügt, um irgendwann behaupten zu können, etwas zu wissen, solange muss man sich auf sein Gefühl verlassen.
Und diese 'try: ... except: ...'-Sachen fühlen sich für mich immer ein wenig nach Hack an. Nach dem Motto "jetzt schau' 'mer mal, dann seh'n 'mer scho."
Sollte man nicht versuchen, ein Programm ohne 'try: ... except: ...' zu entwickeln?
Oder, wenn das kaum möglich ist, sehr sorgsam abwägen, ob kein anderer Weg zum (fehlerfreien) Ziel führt?
Oder ist es letztlich egal? Wem es gefällt, der soll es einsetzen, wo und wie oft er/sie will.

mutetella
Entspanne dich und wisse, dass es Zeit für alles gibt. (YogiTea Teebeutel Weisheit ;-) )
Benutzeravatar
noisefloor
User
Beiträge: 4262
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,
Sollte man nicht versuchen, ein Programm ohne 'try: ... except: ...' zu entwickeln?
Kommt drauf an. Wenn du Nutzereingaben entgegen nimmst oder allgemeiner Daten aus Quellen holst, die du selber nicht kontrollierst, dann macht try...excpt schon Sinn.

try...except macht hingegen keinen Sinn, wenn man seine eigene Nachlässigkeit beim Programmieren kaschieren will. ;-)

Gruß, noisefloor
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

mutetella hat geschrieben:Und diese 'try: ... except: ...'-Sachen fühlen sich für mich immer ein wenig nach Hack an. Nach dem Motto "jetzt schau' 'mer mal, dann seh'n 'mer scho."
Ist es aber nicht. Die Alternative von try..except wären Fehlercodes. So wie man es in C macht. Da man aber in Python anders als in C kein goto hat, würde das in Python noch viel unübersichtlicher werden, da man dann zwangsläufig unleserlich verschachtelte ifs in komplizierteren Fällen braucht.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Da einem der Python-Interpreter selber ja Exceptions um die Ohren haut, könnte man auch davon ausgehen, dass es ok ist, diese zu nutzen ;-) Oder sollte man den Entwicklern nicht zutrauen, die idiomatisch richtigen Sprachfeatures zu nutzen? :twisted:
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Man muss die Exceptions genau eingrenzen, ein blankes try...except ist sicher selten hilfreich, weil damit auch Fehler des Programms verdeckt werden.
Antworten