Seite 1 von 2
überprüfen, ob sys.argv[1] vorhanden
Verfasst: Dienstag 14. Oktober 2008, 16:23
von pheder
Hallo,
ich bin der Neue

Zumindest neu hier im Forum, da gerade angefangen, mit Python zu beschäftigen.
Ich habe vor in meinem Programm vor der Speicherung von sys.argv[1] zu prüfen, ob es dieses überhaupt gibt und so doch etwas unfreundliche Fehlermeldung abzufangen und einen viel freundlicheren Hinweis hinzusetzen

Problem: Ich weiß nicht, wie ich überprüfen kann ob sys.argv[1] belegt ist, bei python.org gibt es die Möglichkeit selbst im Modul nicht, und wenn ich es mit meiner Idee versuche bekomme ich Problemchen mit der Syntax:
Code: Alles auswählen
if not (len(sys.argv[1]) = 0):
rawdata = sys.argv[1]
else:
return 0
Gibt es eine Möglichkeit zu prüfen, ob der entsprechende Parameter mitgegeben wurde?
Ich bedank mich mal schon im vorraus, mfG pheder
Re: überprüfen, ob sys.argv[1] vorhanden
Verfasst: Dienstag 14. Oktober 2008, 16:39
von helduel
Moin,
Code: Alles auswählen
try:
rawdata = sys.argv[1]
except IndexError:
return 0
Gruß,
Manuel
Verfasst: Dienstag 14. Oktober 2008, 16:47
von pheder
Code: Alles auswählen
File "pyload.py", line 33
rawdata = sys.argv[1]
^
IndentationError: expected an indented block
python wehrt sich...
Verfasst: Dienstag 14. Oktober 2008, 16:47
von roschi
hallo!
man sollte, wenn nicht anders moeglich, anstatt '0' und '1', die konstanten 'True' (wahr) und 'False' (falsch) verwenden um zu sagen, ob etwas stimmt oder nicht.
mach also niemals
sondern
oder in deinem fall wuerde es so aussehen:
Code: Alles auswählen
# versuche:
try:
rawdata = sys.argv[1]
# wenn ein 'IndexError' ausgeloest wird,
# brich den try-block ab und mache:
except IndexError:
return False
mfg
roschi
Verfasst: Dienstag 14. Oktober 2008, 16:49
von roschi
du hast was falsch eingerueckt.
Verfasst: Dienstag 14. Oktober 2008, 16:53
von Leonidas
Am einfachsten ist doch einfach die Länge der Liste zu prüfen, analog zu ``argc`` in C:
Code: Alles auswählen
if len(sys.argv) >= 2:
rawdata = sys.argv[1]
else:
return False
Re: überprüfen, ob sys.argv[1] vorhanden
Verfasst: Dienstag 14. Oktober 2008, 16:58
von Darii
pheder hat geschrieben:Problem: Ich weiß nicht, wie ich überprüfen kann ob sys.argv[1] belegt ist, bei python.org gibt es die Möglichkeit selbst im Modul nicht, und wenn ich es mit meiner Idee versuche bekomme ich Problemchen mit der Syntax:
Code: Alles auswählen
if not (len(sys.argv[1]) = 0):
rawdata = sys.argv[1]
else:
return 0
Anmerkung dazu. Vergleich läuft über == und nicht = dadurch hast du deine Fehlermeldung bekommen. Außerdem würde, wenn sys.argv[1] nicht existiert,der Zugriff darauf einen IndexError werfen.
Verfasst: Dienstag 14. Oktober 2008, 17:22
von pheder
Danke, wieder was gelernt, echt tolle Hilfe hier.
Das Problem der Einrückung entstand dadurch, dass ich Copy&Paste verwendet habe und Tabulatoren statt Leerzeichen (wie hier verwendet) gebraucht hätte. ich habe jetzt aber doch Leonidas Lösung verwendet, da diese schön erweiterbar ist (wenn mehr Parameter nötig).
Verfasst: Dienstag 14. Oktober 2008, 18:20
von lunar
Man kann im Übrigen auch Kommandozeilenparser ala getopt, optparse oder argparse verwenden. Die nehmen dir das Parsen der Kommandozeile weitestgehend ab.
Verfasst: Dienstag 14. Oktober 2008, 19:11
von Hyperion
Leonidas hat geschrieben:Am einfachsten ist doch einfach die Länge der Liste zu prüfen, analog zu ``argc`` in C:
Code: Alles auswählen
if len(sys.argv) >= 2:
rawdata = sys.argv[1]
else:
return False
Ist das nicht eigentlich gegen das EAFP-Prinzip? Ich würds denke ich auch so machen, aber das fiel mir grad einfach auf.
Verfasst: Dienstag 14. Oktober 2008, 20:19
von cofi
Hyperion hat geschrieben:Ist das nicht eigentlich gegen das EAFP-Prinzip? Ich würds denke ich auch so machen, aber das fiel mir grad einfach auf.
Nun ja schon, aber wer sagt denn, dass `Look before you leap' verboten ist?

Verfasst: Dienstag 14. Oktober 2008, 22:08
von Leonidas
Hyperion hat geschrieben:Ist das nicht eigentlich gegen das EAFP-Prinzip?
Ja, du hast natürlich recht. Aber die Prüfung erlaubt es, den Code im "wenn das Argument angegeben ist"-Block gar nicht auszuführen und nicht erst x-viele Instruktionen abzuarbeiten, bis dann irgendwann ein Indexerror kommt. Dann ist kein Rollback möglich. Außerdem finde ich die explizite Prüfung einer bestimten Liste klarer als das allgemeine Abfangen von IndexErrors, die ja nicht unbedingt damit zu tun haben müssen, dass zu wenige Argumente übergeben werden.
Natürlich, Python sagt EAFP und es ist oft auch sinnvoll, aber LBYL ist an einigen Stellen expliziter. Es ist natürlich immer eine Sache die man von Situation zu Situation analysiert und für die es keine definitive beste Lösung gibt. Das fällt wohl auch unter die künstlerische Freiheit und auch was man mit dem Code erreichen will: größtmögliche Explizitheit (LBYL) oder größtmögliche Performance (EAFP). Ich denke man sollte Ausnahmen auch wirklich nur produzieren/provozieren und behandeln wenn die Situation eine Ausnahmesituation ist, wohingegen eher zu erwarten ist, dass der User zu wenige Argumente angibt. Du siehst, die Definition wann man was einsetzen würde ist eher Erfahrungssache.
Verfasst: Mittwoch 15. Oktober 2008, 04:31
von snafu
Ich sehe das ganz ähnlich. Eine Exception zeigt für mich so etwas wie einen Fehler an. Beim Weglassen von Argumenten wird aber explizit gewünscht, das Programm eben so auszuführen. Und normalerweise sollte ein Programm dies unterstützen. Exceptions sollte man IMHO für Zugriffsfehler, falsche Benutzereingaben und ähnliches verwenden, also Dingen die außer der Fehlerbehandlung zu keiner Funktionalität im Programm führen.
Verfasst: Mittwoch 15. Oktober 2008, 07:07
von birkenfeld
Solange du sicherstellst, dass alle Exceptions ordentlich behandelt werden, kannst du sie z.B. auch für Flusskontrolle verwenden.
Bei GeneratorExit und StopIteration musst du das sogar (wenn man es auch meistens nicht sieht).
Verfasst: Mittwoch 15. Oktober 2008, 09:07
von helduel
snafu hat geschrieben:Ich sehe das ganz ähnlich. Eine Exception zeigt für mich so etwas wie einen Fehler an. Beim Weglassen von Argumenten wird aber explizit gewünscht, das Programm eben so auszuführen. Und normalerweise sollte ein Programm dies unterstützen. Exceptions sollte man IMHO für Zugriffsfehler, falsche Benutzereingaben und ähnliches verwenden, also Dingen die außer der Fehlerbehandlung zu keiner Funktionalität im Programm führen.
Also ich sehe Exceptions, wie der Namen schon sagt, als Ausnahmen. Das sind nicht zwingenderweise Fehler. Und wenn ich eine Ausnahmesituation habe, dann muss ich sie anders behandeln als den Rest, was durchaus eine weitere Funktionalität mit sich bringen kann.
Bei Kommandozeilenargumenten kann man durchaus geteilter Meinung sein. Ist das Weglassen von Argumenten eher üblich (dann würde ich eher mit if/else arbeiten) oder ist das nur ausnahmsweise so oder gar ein Fehler (dann würde ich eher mit Exceptions arbeiten). Das hängt von Fall zu Fall ab, wie Leonidas schon gesagt hat.
Verfasst: Mittwoch 15. Oktober 2008, 09:31
von lunar
Nun ja, ich würde Kommandozeilenargumente ja mit etwas anständigem wie argparse parsen, dann übernimmt der Parser die Überprüfung
Ich halte es mit dem Zen: "Better explicit than implicit". Ausnahmen sind nicht explizit. Beim Anfangen eines IndexError steht nirgendwo explizit, wie viele Elemente man erwartet. Mehr noch, es ist ja per definitionem nicht mal sicher, dass man tatsächlich den IndexError des Listenzugriffs abfängt. Ein zu großzügiger try-Block kann folglich zu logischen Fehlern führen.
Verfasst: Mittwoch 15. Oktober 2008, 10:00
von helduel
lunar hat geschrieben:Nun ja, ich würde Kommandozeilenargumente ja mit etwas anständigem wie argparse parsen, dann übernimmt der Parser die Überprüfung

Das sowieso, aber wenn wir schonmal dabei waren...
lunar hat geschrieben:Ich halte es mit dem Zen: "Better explicit than implicit". Ausnahmen sind nicht explizit. Beim Anfangen eines IndexError steht nirgendwo explizit, wie viele Elemente man erwartet. Mehr noch, es ist ja per definitionem nicht mal sicher, dass man tatsächlich den IndexError des Listenzugriffs abfängt. Ein zu großzügiger try-Block kann folglich zu logischen Fehlern führen.
Zu großzügig sagt aber schon was aus: Er ist zu großzügig. Mit dem else-Block kann man den try-Block aber auf's Wesentliche reduzieren:
Code: Alles auswählen
mylist = get_list_from_somewhere()
try:
foo = mylist[1]
except IndexError:
do_something()
else:
do_something_with_list(foo)
Wieviele Elemente erwarte ich? Mindestens zwei. Klar, ich sage nicht, dass ich ein drittes erlaube oder verbiete. Aber das interessiert hier auch gar nicht. Wenn
das wirklich so wichtig ist, dann muss ich natürlich besser prüfen. Aber das hängt vom Fall ab. Diese Variante ist IMO für diesen Fall nicht weniger explizit als ein "if len(mylist) == 2" oder "if len(mylist) > 1". Und der IndexError kann nur von meinem Listenzugriff kommen.
Verfasst: Mittwoch 15. Oktober 2008, 10:05
von Leonidas
helduel hat geschrieben:Und der IndexError kann nur von meinem Listenzugriff kommen.
Nicht unbedingt, denn wenn mylist keine Liste ist, kann der Indexzugriff durch irgendwas überschrieben werden, was dann zwar exisiteren kann, aber aus einem anderen Grund einen IndexError wirft

Verfasst: Mittwoch 15. Oktober 2008, 11:03
von helduel
Leonidas hat geschrieben:helduel hat geschrieben:Und der IndexError kann nur von meinem Listenzugriff kommen.
Nicht unbedingt, denn wenn mylist keine Liste ist, kann der Indexzugriff durch irgendwas überschrieben werden, was dann zwar exisiteren kann, aber aus einem anderen Grund einen IndexError wirft

Überredet. Auf der anderen Seite kann auch __len__ überschrieben worden sein und die gibt mir jetzt irgendeine Zahl zurück, die gar nichts mit meinen Elementen zu tun hat. Dann krieg ich trotz Check einen IndexError geworfen, den ich gar nicht abgefangen hab, weil ich ja prüfen tu' und so.

Verfasst: Mittwoch 15. Oktober 2008, 13:55
von snafu
helduel hat geschrieben:Also ich sehe Exceptions, wie der Namen schon sagt, als Ausnahmen. Das sind nicht zwingenderweise Fehler. Und wenn ich eine Ausnahmesituation habe, dann muss ich sie anders behandeln als den Rest, was durchaus eine weitere Funktionalität mit sich bringen kann.
In meinen Augen wird in diesem Fall zuerst der eine (Standard-)Weg probiert und wenn der nicht funktioniert (also eine Exception wirft) werden alternative Wege versucht. Das fällt für mich (bin allerdings nicht wirklich von Fach) unter Fehlerbehandlung (diese muss ja nicht zwingend aus einer Fehlermeldung bestehen). Weitere Funktionalität wird damit jedenfalls nicht geboten. Der User möchte als Ergebnis das zurückbekommen, was ihm die Doku beschreibt, egal wieviele Versuche das Programm intern gebraucht hat. Zumindest sehe ich das so.