überprüfen, ob sys.argv[1] vorhanden

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.
pheder
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2008, 15:56
Kontaktdaten:

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
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

Moin,

Code: Alles auswählen

try:
    rawdata = sys.argv[1]
except IndexError:
    return 0
Gruß,
Manuel
pheder
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2008, 15:56
Kontaktdaten:

Code: Alles auswählen

File "pyload.py", line 33
    rawdata = sys.argv[1]
          ^
IndentationError: expected an indented block
python wehrt sich...
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

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

Code: Alles auswählen

while 1:
    ...
sondern

Code: Alles auswählen

while True:
    ...
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
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Benutzeravatar
roschi
User
Beiträge: 225
Registriert: Samstag 29. März 2008, 18:58
Wohnort: Thueringen, Deutschland
Kontaktdaten:

du hast was falsch eingerueckt.
[size=117]Fuer Alle, die in Python einsteigen wollen, kann ich das Buch [url=http://abop-german.berlios.de/]A Byte of Python[/url] nur waermstens empfehlen![/size]
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

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.
pheder
User
Beiträge: 11
Registriert: Dienstag 14. Oktober 2008, 15:56
Kontaktdaten:

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).
lunar

Man kann im Übrigen auch Kommandozeilenparser ala getopt, optparse oder argparse verwenden. Die nehmen dir das Parsen der Kommandozeile weitestgehend ab.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

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.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

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? ;)
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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.
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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.
Benutzeravatar
birkenfeld
Python-Forum Veteran
Beiträge: 1603
Registriert: Montag 20. März 2006, 15:29
Wohnort: Die aufstrebende Universitätsstadt bei München

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).
Dann lieber noch Vim 7 als Windows 7.

http://pythonic.pocoo.org/
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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.
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.
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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.
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

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 ;)
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
helduel
User
Beiträge: 300
Registriert: Montag 23. Juli 2007, 14:05
Wohnort: Laupheim

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. :twisted:
Benutzeravatar
snafu
User
Beiträge: 6736
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

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