wie bewertet man Exceptions "pythonic"?

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

Freitag 7. April 2006, 00:30

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?
Benutzeravatar
jens
Moderator
Beiträge: 8483
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Freitag 7. April 2006, 06:02

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]

CMS in Python: http://www.pylucid.org
GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mitsuhiko
User
Beiträge: 1790
Registriert: Donnerstag 28. Oktober 2004, 16:33
Wohnort: Graz, Steiermark - Österreich
Kontaktdaten:

Freitag 7. April 2006, 06:14

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.
TUFKAB – the user formerly known as blackbird
BlackJack

Freitag 7. April 2006, 21:19

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

Mittwoch 12. April 2006, 17:13

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.
Antworten