Seite 1 von 1

wie bewertet man Exceptions "pythonic"?

Verfasst: Freitag 7. April 2006, 00:30
von keppla
Hi!
Die Situation sei folgende:

Code: Alles auswählen

class Base:
   def callback(self, **args):
        """ abstract """
        pass

   def do(self, request):
      try:
         self.callback(**request)
      except TypeError, t:
         print "fehlerhafte parameter übergeben"

class Startseite(Base):
   def callback(self, name, begehr, lieblingsfarbe):
       print name, begehr, lieblingsfarbe

class Problem(Base):
    def callback(self, **argmap):
         raise TypeError()
das ganze könnte zB eine Art Framework für dynamische Webseiten sein, für jede anzuzeigende Seite würde man von Base erben. Der Webserver würde dann "do" mit den Requestvariablen aufrufen.
Dank der Funktionalität von Base müssten sich die Funktionen nicht jedesmal mit der Vollständigkeit der Argumente auseinandersetzen.

So weit so gut. Was passiert nun aber, wenn irgendwo unterhalb der funktion ein TypeError verursacht wird? dann wird der fälschlicherweise gefangen, und das ist imho schlimmer als ihn nicht zu fangen, da er falsch interpretiert wird.
eine alternative wäre hier LBYL, was aber unpythonic wäre.

ich bin schon häufiger auf das problem gestossen, auch in anderen formen. gibt es da einen hübschen weg, der sich mir zZ entzieht?

Verfasst: Freitag 7. April 2006, 06:02
von jens
Versuchst du gerade WSGI nachzubauen??? Sieht für mich ganz danach aus ;) Da heißt es nur nicht do() sondern process_request() ;)

Schau mal hier: [wiki]Colubrid/Hello World[/wiki]

Verfasst: Freitag 7. April 2006, 06:14
von mitsuhiko
jens hat geschrieben:Versuchst du gerade WSGI nachzubauen??? Sieht für mich ganz danach aus ;) Da heißt es nur nicht do() sondern process_request() ;)
Das ist colubrid. in WSGI heißt es __iter__
Schau mal hier: [wiki]Colubrid/Hello World[/wiki]
... für ein Colubrid beispiel :-)

@keppla: Wenn du es WSGI kompatibel machst schaut das schonmal nicht schlecht aus :-) Aber warum soll TypeError gefangen werden? Ich fang exceptions nur, wenn ich das in eine debugging middleware gebunden hab.

Verfasst: Freitag 7. April 2006, 21:19
von BlackJack
Ich würde die Ausnahme in der Basisklasse überhaupt nicht behandeln. Generell sollte man Ausnahmen nur dann behandeln, wenn man sie wirklich behandeln kann, also in irgendeiner Weise gezielt darauf reagiert. Gerade wenn man Code schreibt, der von "höheren Schichten" benutzt wird, liegt die Verantwortung eher dort.

Abstrakte Methoden sollten per Konvention übrigens die `NotImplementedError()` Ausnahme auslösen.

Verfasst: Mittwoch 12. April 2006, 17:13
von keppla
Versuchst du gerade WSGI nachzubauen
nene, ich HAB nur mal sowas in PHP "nachgebaut" (da kannte ich Rails und Konsorten noch gar nicht, hab es quasi schlechter parallel erfunden). Es gibt halt nur ein prima Beispiel ab, allein, weil das Muster ja jedem hier bekannt zu sein scheint ;)
@keppla: Wenn du es WSGI kompatibel machst schaut das schonmal nicht schlecht aus Smile Aber warum soll TypeError gefangen werden?
Der Typeerror wird gefangen, wenn der "Seite" falsche Parameter übergeben werden sollen. Im hypothetischen Beispiel soll nämlich die Fehlerbehandlung nicht das Problem der Seite sein. Und eine Funktion per ** mit falschem inhalt aufzurufen, verursacht einen TypeError.
Ich fang exceptions nur, wenn ich das in eine debugging middleware gebunden hab.
Ich dachte, es sei Pythonic, erst zu Probieren, und bei Bedarf das Problem zu behandeln.
Ich würde die Ausnahme in der Basisklasse überhaupt nicht behandeln.
Also sollte man im hypothetischen Beispiel mit ner falschen Adresse den Server abschiessen können?
Generell sollte man Ausnahmen nur dann behandeln, wenn man sie wirklich behandeln kann, also in irgendeiner Weise gezielt darauf reagiert.


Kann ich doch. Wenn die Exception durch falsche Parameter verursacht wird, wäre die gezielte Reaktion, dem User ne Fehlermeldung mit dem Inhalt "Falsche URL" zu senden, wenn, die Exception durch eine kaputte Funktion verursacht wurde, dem User eine Entschuldigung schicken, und den Fehler loggen.
Gerade wenn man Code schreibt, der von "höheren Schichten" benutzt wird, liegt die Verantwortung eher dort.
Das Problem ist hier aber, dass, wenn dieser Verantwortlichkeit mal nicht nachgekommen wird, der Fehler falsch diagnostiziert wird.